Deep Dive into HTL in AEM- Sightly and Rendering Script

Hello, Coder’s! In this article we’ll deep dive into HTL and will learn basic to advance concepts of HTL and try to understand why we used HTL in AEM. So, Hypertext Template Language (HTL) is a recommended server-side template system for HTML in Adobe Experience Manager. We also call HTL as Sightly or Sly. Basically, HTL expressions and tags gets convert into HTML code at run time. Previously, in older version of AEM we used JSP as server-side template system for HTML but after introducing HTL by adobe we use HTL over JSP, and also it is recommended to use HTL, as it is more easier and have other benefits which we have described below. Like JSP, HTL also provides us implicit objects such as resource, component, properties, style, request, response, log, sling, etc. They provides some global object which is really helpful.

Why adobe recommend to use HTL over JSP ?

So HTL used because of simplicity, increased security, cost efficient, performance and code reusability etc. Also, HTL offer a highly productive enterprise-level web framework that increase security, and allows HTML developers to work independently without having Java knowledge to better participate in AEM projects.

Now, I am very sure, you may have a question that, why even required these HTL’s and where we used. So AEM used rendering script to render content to web pages and HTL is rendering script. I have explained rendering scripts below.

HTL Syntax

It is start with <sly></sly> but, it can be used within the HTML tags, all HTL properties, attributes and expressions can be used within HTML without <sly> tag.

Code example of helloworld.html file of helloworld component.

Here ${properties.text}, data-sly-use, data-sly-test are the HTL expressions and attributes, we have covered all these expression and attributes one by one in this article. You can create component through Sightly.

List of some useful and daily used HTL attributes/expression and objects

HTL expression can also apply with HTML value, and HTL attributes are also added within

HTML attributes.

like in HTML <div here-htl-attributes>${here-htl-expression}</div>

Some Global HTL Objects

  1. ${properties} : It gives list of properties of the current resource. So if in your resource have properties then we can easily taken properties value by this object and property name,
    Eg: I have a property named fname which have value Shahid then in HTL we can simply use ${properties.fname}, so it will take value from the resource properties from where it ask to load(rendering script) and print in your presentation layer.
  2. pageProperties : It gives list of all the current page related properties value, like page title, modified by etc and we can call as same as properties object with the property name
  3. inheritedPageProperties: it gives list of inherited page properties of the current page.
  4. wcmmode: This java backed object here are the documentation. you can explore their methods and uses.

    Many others object are present and some java backed object are also there, you can go to official documentation if you want to learn learn more about global objects

Lets explore some HTL attributes.

1). data-sly-set

: It is used to set variable in html and once you create variable then you can use anywhere in the elements

Code Example:

<sly data-sly-set.name="Shahid"/>
<div>${name}</div> 

//it will show in Shahid in div element text

2). data sly use

: This is used to initialize a Java class/JavaScript object or even you can also initialized any other HTML templates.
Code example:

<div data-sly-use.model="com.adobe.aem.guides.wknd.core.models.Myblogs">
          ${model.name}
</div>

here data-sly-use is the use to initialized Myblogs class object to HTML and here by model object name we can access all method of Myblogs class, like I have used name method here.

3). data sly test

: As name has test keyword, it shows something will be test or based on some conditions we can implement rest of the thing.

Code Example

<h1 data-sly-test="${isChecked}">Shahid</h1>

// if else code

<div data-sly-test.checked="${ isChecked ||  isModified}">when true this will add</div>
<div data-sly-test="${!checked}">Else this will add</div>

here if condition is true or false then only these element will be generated in final markup.

4). data-sly-repeat

: It repeat the element based on what list you pass, it iterate till size of your list. It repeats with itself and childrens.

Code Example

// suppose in MyBlogs class model have a method which return list of all page name 
// we assume method name List <String> getListOfPages();
<div data-sly-use.model="com.adobe.aem.guides.wknd.core.models.Myblogs">
          <ul>
                  <li data-sly-repeat.myPages=${model.listOfPages}>${myPages.page}</li>
           </ul>
</div>
// li tag will be render in DOM, and this will iterate themselves as total length of list

5). data-sly-list

: It repeat the children elements based on list, same code I have written as data-sly-repeat so that you would understand and diffrenciate easily.

Note: Only difference in data-sly-repeat and data-sly-list is data-sly-repeat iterate elements including themselves but data-sly-list iterate only child node.

Lets, take above example, I am taking ul tag and li tag to demonstrate the difference.

Code Example

 -------data-sly-repeat-------
           <ul data-sly-repeat.myPages=${model.listOfPages}>
                  <li>${myPages.page}</li>
           </ul>

------result will be -----
          <ul>
                 <li>Page 1</li>
          </ul>

          <ul>
                <li>Page 2</li>
          </ul>

          <ul>
                 <li>Page 2</li>
          </ul> so on.....................

----------------------------------------------------------------

-----data-sly-list------
           <ul data-sly-list.myPages=${model.listOfPages}>
                  <li>${myPages.page}</li>
           </ul>

------result will be -----
          <ul>

             <li>Page 1</li>



             <li>Page 2</li>


             <li>Page 2</li>so on.....................
         </ul>

6). data-sly-template

:this attribute is use to create html template and this can be call from other html and will be included where its called.

Code Example:

<template data-sly-template.templateModelName="${@ modelobject}">

<h1>${model.title}</h1>

</template>

// I have demonstrated with an example (https://itsshahid.com) search deep dive in htl
//here I have created two template in single htlm file.
// within same file you can create many html template and call anyone or all as per your need

<template data-sly-template.templateModelNameTwo="${@ customdata}">

<h1>${customdata}</h1>

</template>
data-sly-template-aem

Above I have added two template within same html file to separate and we can call anyone or both as per our requirements.
Variable name is used to identify template during calling.
parameter is used to pass object/data to templates.

7). data-sly-call

: this attributes used to call created template(above I have created in data-sly-template example), and this can add anywhere in the html file.

Code Example:

<div data-sly-use.model="com.adobe.aem.guides.wknd.core.models.Myblogs"
     data-sly-use.headtitledemodel="resultsemailmodal.html">

     <sly data-sly-test.title="${model.title}">
        <sly data-sly-call="${headtitledemodel.templateModelName @ modelobject=model}"></sly>
     </sly>

     <sly data-sly-test="${!title}">
        <sly data-sly-call="${headtitledemodel.templateModelNameTwo @ customdata='my custom title'}"></sly>
    </sly>


</div>

Now you can see bold highlighted code flow. lets understand step by step.
first, I have use data-sly-use to include whole html file as an variable or reference.
second, I have used data-sly-call to call the templated with help of variable.
I have call both template based on condition, like, templateModelName template only call when we have title true else on false we have call templateModelNameTwo template.

data-sly-call

8). data-sly-include

: this attribute is used to include html, this will include whole HTML DOM where we have added. In data-sly-include attributes during calling we can not pass object or variable to calling html but we can achieve this by using template and call attribute which is already explained above.

Code Example:

    <div class="hello" data-sly-include="custom.html">
            your included html file will be add within this div.hello tag.
    </div>
data-sly-include

9). data-sly-resource

:this attribute is use to add another component in acomponent, by data-sly-resource we can add whole component with authoring dialog.

Code Example:

   <sly data-sly-resource="${'textcomponent' @ resourceType='wknd/components/text'}"/>
data-sly-resource

here textcomponent resource name is a name to identify resource, and it is helpful if you need same html in different place but want to authored data same, then simply we can copy paste whole ( <sly data-sly-resource=”${‘textcomponent’ @ resourceType=’wknd/components/text’}”/> ) without changing name of resource. Lets understand below code.

   <sly data-sly-resource="${'textcomponent' @ resourceType='wknd/components/text'}"/>
   <sly data-sly-resource="${'textcomponent' @ resourceType='wknd/components/text'}"/>

here html will render two time but component resource will be shared by both, means authering dialog will be only one. So when you see in auther mode then only one component available to author. If you changes name (textcomponent) to something else then component will be add two time and cq-dialog will need to be configure separately for both components.

What are Rendering Scripts ?

A rendering script is a piece of code or a script that defines how the content should be rendered and displayed on a web page. So what you written in .html or .Jsp file or it may be use HTL and javascript, all are renders content. It is an essential part of the AEM component architecture and used to define the logic for generating the HTML output for a specific component or template.

There are primarily three types of rendering scripts used in AEM:

1). HTL (HTML Template Language): HTL, formerly known as Sightly, is the recommended and default templating language in AEM. It is a modern, secure, and easy-to-use language that separates the logic from the presentation layer. HTL templates are written using HTML-like syntax and allow you to incorporate dynamic logic through expressions and statements. The primary file extension for HTL templates is .html

<div class="my-component">
    <h1>${properties.title}</h1>
    <p>${properties.description}</p>
</div>

2). JSP (JavaServer Pages): AEM also supports traditional JSP for rendering components. JSP is a Java-based technology that allows you to embed Java code within HTML pages. However, HTL is preferred over JSP due to its simpler syntax and improved security features. The file extension for JSP templates in AEM is .jsp.

<%@include file="/libs/foundation/global.jsp"%>
<div class="my-component">
    <h1><%= properties.get("title", "Default Title") %></h1>
    <p><%= properties.get("description", "Default Description") %></p>
</div>

3). JavaScript-Based Rendering: In addition to HTL and JSP, AEM also allows you to use JavaScript and client-side frameworks to render components. This is often used in conjunction with HTL or JSP to add interactivity and dynamic behavior to the components on the client-side. JavaScript-based rendering is commonly implemented using client libraries and front-end frameworks.

<div class="my-component">
    <h1>${properties.title}</h1>
    <p>${properties.description}</p>
    <button id="btn">Click Me</button>
</div>

and using this HTML we change dynamically or render dynamically by javascript like I’m using btn id to add click event

(function() {
    // JavaScript-based interactivity
    var button = document.getElementById('btn');
    button.addEventListener('click', function() {
        alert('Button Clicked!');
    });
})();

I have written example code you should always write javascript code with AEM best practice guidelines.

Thank you!

Leave a Comment