Sunday, March 4, 2018

Deep Dive in HTL/Sightly in AEM 6.3

Hello Everyone,

The term “sightly” or “HTL” is not very new to all of us. We have been developing our components in HTL in place of “JSP” since long.

But as it is little hard to remember all the syntax, In this blog I am trying to cover all the possible block statements in HTL/sightly with use cases as well.

How to include parsys in HTL/Sightly

<div data-sly-resource="${'parsys' @resourceType = 'wcm/foundation/components/parsys'}"></div>

While included parsys in the Page Component, you need to add init.jsp in the page.
<sly data-sly-include="/libs/wcm/core/components/init/init.jsp"/>

Note: Don’t add init.jsp on every page or component, where you need parsys to include. Just add it in base page component and use it everywhere.

How to include clientlibs in a page OR a component in HTL/Sightly

While using single clientlibs:
<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"
data-sly-call="${clientLib.all @ categories='apps.aem-learning'}"/>

While using multiple clientlibs:
<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"
data-sly-call="${clientlib.all @ categories=['myCategory1', 'myCategory2']}"/>

Note: Here keyword “all” stands for all the JS and CSS files. If you want to call JS and CSS specifically, replace all keyword with “CSS” or “JS”.

Difference between data-sly-list and data-sly-repeat
The difference between data-sly-list and data-sly-repeat is that list just iterates the items written inside its condition.
Example:
<ul data-sly-list="${ currentPage.listChildren }">
   <li>  ${item.name} </li>
</ul>

The DOM structure of the list statement will be:
Fig 1: DOM Structure of data-sly-list statement
But if you put the same statement with data-sly-repeat, it will iterate the complete structure including the conditional statement as well.
Example:

<ul data-sly-repeat="${ currentPage.listChildren }">
   <li>  ${item.name} </li>
</ul>

The DOM structure of the above statement will be:
Fig 2: DOM Structure of data-sly-repeat statement
If you want to have the same output from repeat, like list, you need to write something like:

<ul>
      <li data-sly-repeat.child="${ currentPage.listChildren }">
  ${child.name}
      </li>
</ul>

An additional itemList (respectively <variable>List in case a custom identifier/variable was defined using data-sly-list.<variable>) identifier is also available within the scope, with the following members:

  • index: zero-based counter (0..length-1)
  • count: one-based counter (1..length).
  • first: true for the first element being iterated.
  • middle: true if element being iterated is neither the first nor the last.
  • last: true for the last element being iterated.
  • odd: true if index is odd.
  • even: true if index is even

In case of default identifier:
<ul data-sly-list="${currentPage.listChildren}">
   <li data-sly-test="${ itemList.even}">${item.title}</li>
</ul>
In case of custom identifier:
<ul data-sly-list.child="${currentPage.listChildren}">
       <li data-sly-test="${childList.even}">${child.title}</li>
</ul>
In AEM 6.4,HTL introduces some attributes for list and repeat that allows to control the iteration through the following options.
  • begin: iteration begins at the item located at the specified index; first item of the collection has index 0
  • step: iteration will only process every step items of the collection, starting with the first one
  • end: iteration ends at the item located at the specified index (inclusive)
<ul data-sly-list.child="${currentPage.listChildren @ begin = 0, step = 5 ,end = 9}">
   <li>${child.title}</li>
</ul>

How to iterate map objects in HTL/sightly

<sly data-sly-use.model="com.aem.project.core.models.HelloWorldModel"/>
<p data-sly-test.myMap="${model.map}" data-sly-repeat.mapItem="${myMap}">
   <span>key: ${ mapItem }</span>
<span>value: ${myMap[mapItem]}</span>
</p>

Note:Always use the identifier instead of default “item” variable for list of block and repeat statements.

How to use data-sly-use in HTL/Sightly

Initializes a helper object (defined in JavaScript or Java) and exposes it through a variable.
The identifier set by the data-sly-use block element is global to the script and can
be used anywhere after its declaration:
<sly data-sly-use.model="com.aem.project.core.models.HelloWorldModel"/>
       ${model.path}
data-sly-use with input parameters:

<div data-sly-use.model="${'com.aem.project.core.models.HelloWorldModel'
@ pageTitle=currentPage.title , pageNae = currentPage.name}">
${model.pageTitle}
${model.name}

Note: Try to place use data-sly-use statements only on top-level elements.

How to use data-sly-test in HTL/Sightly

  • data-sly-test behaves like an if condition in HTL.It removes the whole element from the markup if the expression evaluates to false.
<meta data-sly-test.keywords="${properties.keywords}" name="keywords" content="${keywords}"/>
<p data-sly-test="${wcmmode.edit}">You are in edit mode</p>

Note that the identifier contains the value of the condition as it was (not casting it to a Boolean value):
  • Always cache test block statement results in an identifier if it repeats itself. There may be a need of using a value at various place in a single HTML, so it’s good to have a variable having that value and use it at all places.

<sly data-sly-test.path="${currentPage.path}"/>
Now ${path} can be used to show the path of currentPage.

What is the use of sly tag?
sly tag don’t let be the statements the part of DOM and clears out the rendered HTML and get rid of additional divs. You can also use data-sly-unwrap to remove the element from DOM.

Note: Always use existing HTML elements for your block statements if possible.

Demonstration Video On


How to use data-sly-element in HTL/Sightly

Replaces the element's tag name:
The element name is automatically XSS-protected with the elementName context, which by the way doesn't allow elements like <script>, <style>, <form>, or <input>.
<h1 data-sly-element="${properties.elementName}">This is element example </h1>

It will replace the h1 tag with the value of elementName.

Note: context='elementName' allows only the following element names:
section, nav, article, aside, h1, h2, h3, h4, h5, h6, header, footer, address, main, p, pre, blockquote, ol, li, dl, dt, dd, figure, figcaption, div, a, em, strong, small, s, cite, q, dfn, abbr, data, time, code, var, samp, kbd, sub, sup, i, b, u, mark, ruby, rt, rp, bdi, bdo, span, br, wbr, ins, del, table, caption, colgroup, col, tbody, thead, tfoot, tr, td, th

data-sly-resource in HTL/Sightly
Includes the result of rendering the indicated resource through the sling resolution and rendering process. It works completely on the concept of sling resolution.

Manipulating the path of the resource.
<article data-sly-resource="${@path='path/to/resource'}"/>

Examples:
<article data-sly-resource="${@path='/content/we-retail/language-masters/en
/equipment/jcr:content/root/hero_image'}"/>

<article data-sly-resource="${@path='/content/we-retail/language-masters/en
/equipment/jcr:content/root',appendPath='hero_image'}"/>

<article data-sly-resource="${@path='hero_image',prependPath='/content/
we-retail/language-masters/en/equipment/jcr:content/root'}"/>

Replace the selector from the existing ones.
<article data-sly-resource="${'path/to/resource' @selectors='selector'}"></article>
<article data-sly-resource="${'path/to/resource' @selectors=[''selector1',''selector2']}">
</article>

Examples:
<article data-sly-resource="${'/content/we-retail/language-masters/en
/equipment/jcr:content/root/hero_image' @selectors='s1'}"></article>

<article data-sly-resource="${'/content/we-retail/language-masters/en
/equipment/jcr:content/root/hero_image' @selectors=['s1','s2']}"></article>

Add a selector to the existing ones.
<article data-sly-resource="${''path/to/resource' @addSelectors='selector'}"></article>

Examples:
<article data-sly-resource="${'/content/we-retail/language-masters/en/equipment/jcr:content/root/hero_image' @addSelectors='s1'}"></article>

Remove the selectors from the existing ones.
<article data-sly-resource="${'path/to/resource' @removeSelectors='s1'}"></article>

Examples:
<article data-sly-resource="${'/content/we-retail/language-masters/en/equipment/jcr:content/root/hero_image' @removeSelectors='s1'}"></article>

Remove all selectors.
<article data-sly-resource="${'path/to/resource' @removeSelectors}"></article>

Overrides the resourceType of a resource.
<article data-sly-resource="${'path/to/resource' @resourceType = 'my/resource/type'}">
<article>

Changes the WCMMode
<article data-sly-resource="${'path/to/resource' @wcmmode='disabled'}"></article>

By default, The AEM Decoration Tags are disabled, the decoration tagName option
allows to bring them back and the cssClassName to add classes to that element.
<article data-sly-resource="${'path/to/resource' @ decorationTagName='span',
cssClassName='className'}"></article>

Difference between selectors and addSelectors Attribute with an example
selectors: selectors attribute is used to replace the selector.
<article data-sly-resource="${'/content/we-retail/ca/en/jcr:content/root/hero_image/default.s1.html' @ selectors='s2'}"></article>
It renders s2.html

addSelectors: is used to add the selector.
<article data-sly-resource="${'/content/we-retail/ca/en/jcr:content/root/hero_image/default.s1.html' @ selectors='s2'}"></article>
It renders s1.s2.html script.

Demonstration Video on data-sly-resource:


Note: In the above blog, I am calling one sling model named HelloWorldModel.java, which can be seen on github.
If you have any query or suggestion then kindly comment or mail us at sgaem.blog02@gmail.com

Hope it will help you guys !!
Thanks and Happy Learning.

15 comments:

  1. Excellent thanks and the YouTube video is great also.

    ReplyDelete
  2. your tutorials are very helpful. can you please make a tutorial on workflow?

    ReplyDelete
  3. Please use real time examples to demonstrate, these examples are copied as it is from helpx site.

    ReplyDelete
  4. Nice article for Sightly information.
    Also found one more article for Adobe AEM with defined information
    https://aemintroduction.blogspot.com/

    ReplyDelete
  5. This comment has been removed by a blog administrator.

    ReplyDelete
  6. Can we use "data-sly-resource" in JSP file?

    ReplyDelete
  7. This comment has been removed by the author.

    ReplyDelete
  8. Am trying to include a componentA in another componentB using data-sly-resource. Under the /content folder I could see that componentA only when I author the dialog. And sling:resourceType is not set in the properties of componentA? Is this the expected behavior. Can you please suggest?

    ReplyDelete
  9. Great Article!

    Just a little confuse here,
    "Overrides the resourceType of a resource.
    "

    Why would us want to override the resourceType of a certain resourceType?
    Is there a scenario for it?

    Thanks

    ReplyDelete