Understanding HTL Syntax in AEM
HTL syntax is divided into two main parts: Block Statements and HTL Expressions.
MVC Design Pattern In AEM
HTL Expression:
As we saw in the top first Diagram HTL syntax is divided into block statements and HTL Expression
HTL expressions display data from variables, arrays, or objects on an HTML/HTL page.
HTL Block Statements
HTL Block Statements control logic and structure within the template.
Logic File
Let's define a logic file logic.js containing our logic, you can define your login in sling modals as you like.
function test(){
std = [
{
name:"Awais",
title : "Engineer",
},
{
name:"Zahid",
title : "Professional",
},
{
name:"Kamran",
title : "Student",
},
];
return {
std: std,
Arr: ["School","College","University"],
page: pageManager.getPage("/content/we-retail/us/en")
}
};
use(test);
HTL Template
<!DOCTYPE html>
<!--/* Calling the server-side JS script for all view logic that Sightly cannot do */-->
<html data-sly-use.logic="logic.js">
<head>
<!--/* Expressions allow to easily output variables will set the currentPage Title*/-->
<title>${currentPage.title}</title>
<meta charset="utf-8">
</head>
<body>
- <!--/* Two different ways to show the current Page title first is Block Statement and 2nd is HTL Expression /-->
<div data-sly-text = "${currentPage.title}"></div>
<div>${currentPage.title}</div>
Output
HTL REPL
HTL REPL
- <!--/* use to change the value of an attribute: in the bottom example, the value of id will be changed by the value of currentPage.title*/-->
<div id="working" data-sly-attribute.id = "${currentPage.title}"></div>
Output
output will not shown on the page but it will update the value of the id with HTL REPL bcoz its current page title
- <!--/* use to change the value of Element : in following example the h6 will be changed by the h1*/-->
<h6 data-sly-element="h1">replace Element Value</h6>
Output
It will print Replace Element Value in H1 Tag
- <!--/* following example is showing the child pages of current page repeat is same as list*/-->
<div data-sly-repeat="${currentPage.listChildren}">
<a href="${item.path}">${item.name}</a>
</div>
Output
us bcoz this current page having only child page that is US
- <!--/* following example is showing the child pages of the page that you are getting in logic.js file, and begin is telling starting index and end is telling ending index.*/-->
<div data-sly-list="${logic.page.listChildren @ begin=1 , step=1, end =5}">
<li><a href="${item.path}">${item.name}</a></li>
</div>
Output
- <!--/* Following example is used to iterating the array of object that is defend in logic.js file you can print as well index , count or can check EVEN ODD etc*/-->
<ul data-sly-list="${logic.std}">
<li>
- ${item.name}
- ${item.title}
- (Index : ${itemList.index})
- (count : ${itemList.count})
- (first : ${itemList.first})
- (middle : ${itemList.middle})
- (last : ${itemList.last})
- (Odd : ${itemList.odd})
- (Even : ${itemList.even})
</li>
</ul>
Output
- -Awais - Engineer - (Index : 0) - (count : 1) - (first : true) - (middle : false) - (last : false) - (Odd : true) - (Even : false)
- - Zafar - Professional - (Index : 1) - (count : 2) - (first : false) - (middle : true) - (last : false) - (Odd : false) - (Even : true)
- - Kamran - Student - (Index : 2) - (count : 3) - (first : false) - (middle : false) - (last : true) - (Odd : true) - (Even : false)
- <!--/* Following example we are creating x variable and printing its value*/-->
<p data-sly-set.x="${5}"></p>
value : ${x}
Output
value : 5
- <!--/* working will print when x have value, its mean it will work like if statement*/-->
<p data-sly-set.x="${12}"></p>
<p data-sly-test = "${x}">
working
</p>
- <!--/* In following way we use oprators*/-->
<p data-sly-test = "${false || true}">
working
</p>
</div>
</body>
</html>
Accessing JSON Output in AEM
Tip: Add .7.json at the end of your AEM page URL to view structured JSON output.
example : http://localhost:4502/editor.html/content/we-retail/us/en/men.html.7.json
Accessing Child Elements
<div data-sly-list.child="${resource.getChildren}">
<div data-sly-list.childItem="${child.getChildren}">
<sly data-sly-test="${childItem.hasChildren}"> // if having children
if you want to loop the child pages you need to make it again here
<p class="text-success">${childItem.pageLabel}</p>
</sly>
<sly data-sly-test="${!childItem.hasChildren}"> //if not having children
<a href="" class="text-success"> ${childItem.pageLabel} </a>
</sly>
</div>
</div>
SOME CONDITIONAL RENDERING
Directly accessing any properties from 7.json
${properties['navigationPages/item0/megaMenu/item2/subPageLabel']}
Conditionally Iterating Over Child Resources in HTL
<div data-sly-list.child="${resource.getChildren}">
<ul data-sly-list.item="${child.name == 'columnTwo' ? child.getChildren : []}">
<li>
<p>${item.label}</p>
<p>${item.link}</p>
</li>
</ul>
</div>
This HTL code iterates over the child resources of the current component using data-sly-list.child="${resource.getChildren}". It then checks if a child has the name "columnTwo", and if so, it retrieves its children using data-sly-list.item="${child.name == 'columnTwo' ? child.getChildren : []}". Each child of "columnTwo" is then displayed in a list, showing its label and link properties. If "columnTwo" does not exist or has no children, nothing is rendered.
Instead of Two Loops, we can get children in one Iteration too.
<div class="tab-content mt-3" id="myTabContent">
<!--*/ All-Tab /*-->
<div class="tab-pane fade show active" id="all" role="tabpanel"
aria-labelledby="all-tab">
<div data-sly-test="${resource.getChildren[0]}"
data-sly-list.tabsItems="${resource.getChildren[0].getChildren}" class="row">
<div data-sly-test="${tabsItems.getChildren[0]}"
data-sly-repeat.items="${tabsItems.getChildren[0].getChildren}"
class="col-lg-4 offer-card-wrap">
<div class="offer-card">
<div>
<img src="${items.cardImage}" alt="offer thumbnail" class="thumbnail" />
<h4 class="title">${items.cardTitle}</h4>
</div>
<div class="details">
<span class="date">
${properties.validityLabel} ${'yyyy-MM-dd' @ format=items.date, type='date'}
</span>
<a class="link" href="${items.link @ extension = 'html'}">
${properties.learnMoreLabel}</a>
</div>
</div>
</div>
</div>
</div>
Problem Statement (Generalized & Clear)
We have an existing component called faqs that is already used on more than 10 pages in production.
Each page contains different content inside the cici component.
For example:
- Web-Home → faq (Home content)
- Web-Service → faq (Service content)
- Web-Gold → faq (Gold content)
All these pages are already deployed and live in production.
New Requirement
Now we need to create 10 new pages for another section (for example, Mobile pages).
On these new pages:
We created a new component called vivi
This vivi component has a different design/layout
But it must display the same content that already exists inside the corresponding faq component on the Web pages
Solution
<section>
<div>
<h1>${properties.title}</h1>
<h1>${properties.webPage}</h1>
<!-- webPage is the path of the page in which the component is added, we are getting
this path from cq: dialogue
example: /content/projectName/language-master/en/cards
-->
<sly data-sly-test="${properties.webPage}">
<!-- Page path+ componentPath on the page can get from CRXDLITE from top search-->
<sly data-sly-set.cici="${properties.webPage}/jcr:content/root/container/faqs" />
<sly data-sly-use.ciciPath="${cici}" />
<!-- Using data-sly-use to fetch and display only the content of the
faq component from webPage -->
<h1>${ciciPath.title}</h1>
<!-- Using data-sly-resource to embed the entire faq component
(layout + content) from the webPage page -->
<sly data-sly-resource="${ciciPath @ wcmmode='disabled'}" />
</sly>
</div>
</section>
How to get the component Path on the Page
Click here for:
Global Object
0 comments: