March 15, 2020
Estimated Post Reading Time ~

Sightly or HTL

Sightly means "pleasing to eyes"
·                It is a new and powerful HTML templating language used in AEM. 
·                It is expected to be a replacement of JSP and ECMA script, however, you will not be able to write complex code using sightly.  
·                The expressiveness of sightly is intentionally limited as you should be using real programming languages like Java to write complex code. Although you can easily pass inputs via sightly to Java code and also easy to use the output from Java code in front-end using Sightly.

Code Syntax : 

   1.   Sightly code is written using dollar sign '$' and braces '{}' ,
         e.g ${currentPage.title} where currentPage is a global object and title is a variable.
     
           You can use global objects as listed in [0]

   2.  You can add sightly as an attribute to any HTML element. In this case, dollar sign and braces are not required.
        e.g  < div data-sly-include="main.html"/>   where data-sly is used to indicate sightly language and include is action.

HTL Introduction
The HTML Template Language (HTL) provides separation of concerns between the logic and the markup. Compared to JSP, HTL provides a good security model and ensures project efficiency. HTL has powerful extension mechanisms for reuse of logic and of mark-up.

The HTML Template Language comprises of

i). Expression Language
: Used to insert pieces of content into the rendered markup.
ii). Block statements: Used to define statements over blocks of markup (conditions/iterations)

HTL is strict so that it does not allow to mix code inside the markup. HTL uses the 'Use-API extension' technique to easily execute code from the HTL template.

The common and recommended method is to write business logic in Java. In case the component needs some view-specific changes from what the Java API provides, it is recommended to use server-side executed JavaScript.
Advantages:
Increased Security
HTL gets compiled into Java Servlets, during this process the expressions and the HTL data attributes are both evaluated entirely server-side, thus the view source option of the HTML page does not show anything.

Reduced Costs
HTL provides increased security, simplified development and improved team collaboration, faster time to market (TTM), reduced effort and lower total cost of ownership (TCO).

Simplified Development

The HTML Template Language is easy to learn for a developer who knows basic HTML and its syntax and features are purposely limited to ensure that it stays simple and straight-forward.

HTL Syntax
HTL is strict with the syntax. Considering the types there are two types of HTL syntax.

Block Statements
Basically, they are custom data attributes added directly to existing HTML.
Block statements are prefixed with data-sly.

Below given the block statements.
HTL sly-test
HTL sly-use
HTL sly-unwrap
HTL sly-text
HTL sly-attribute
HTL sly-element
HTL sly-repeat
HTL sly-list
HTL sly-resource
HTL sly-include
HTL sly-template
HTL sly-call

Expression Language
HTL expressions are evaluated at run time and their value is injected into the outgoing HTML stream.
HTL expressions are delimited by characters ${ and }.

Below given the Expression Languages.
HTL Variables
HTL Literals(Boolean, Number,Strings,Arrays)
HTL Operators(Logical Operators, Conditional (ternary) Operator, Comparison Operators, Grouping parentheses)
HTL Options(String Formatting,Internationalization,Array Join,Display Context)

HTL Options

Options are used with block statements, Symbol @ starts the option expression. Options can have a value, which may be either a variable or a literal. Options are mainly used for String Formatting, Internationalization, Array Join.

String Formatting
${'Page {0} of {1}' @ format=[current, total]}

Internationalization
${'Page' @ i18n, hint='Direction for translators', source='user'}

Array Join
${['1', '2'] @ join='; '}

Display Context
 HTL will automatically detect the context of expressions and escape them appropriately to ensure security and avoid XSS vulnerability. The context behavior may need to be adjusted as our coding needs. This can be explicitly set to override the automatic behavior of HTL. HTL display context refers to its location within the structure of the HTML page.

 Display Context Settings are given below
·                 text
·                 html
·                 attribute
·                 uri
·                 number
·                 attributeName
·                 elementName
·                 scriptToken
·                 scriptString
·                 scriptComment
·                 styleToken
·                 styleString
·                 styleComment
·                 unsafe

  //Safely output the markup
 ${properties.richText @ context='html'}
HTL Variables
Variables hold the data values or objects.
Below given the list of all objects which can be accessed to HTL.
--Enumerable--
--Java-backed--
properties pageProperties inheritedPageProperties
component componentContext currentDesign currentNode currentPage currentSession currentStyle designer editContext log out pageManager reader request resolver resource resourceDesign resourcePage response sling slyWcmHelper wcmmode xssAPI

We can access the properties of a variable in two ways.

1)Dot notation: simpler,preferred for most cases.
//access the page title
${currentPage.title}

2)Bracket notation: to access properties dynamically or to access properties that contain invalid identifier characters.
//access the page title
${currentPage['title']} or ${currentPage["title"]}

Thumb rule for valid names
 start with a letter (A-Z and a-z), or an underscore (_), and subsequent characters can also be digits (0-9) or colon (:).

Access unicode or invalid identifier characters
${properties['title propertyå']

Access Members Dynamically
${properties[myVarProperty]}

Access variables which have 'Null' Values
${currentNode.lastModified.time.toString}

HTL Literals
Literals hold a constant(fixed) value. It can be of 4 types mainly.

Boolean: Represents on-off condition. It can be accessed as
${true} ${false}

Numbers: HTL Supports only positive digits, not negative numbers or floating.
${11}

Strings: Holds text values
${'mytext1'} ${"mytext2"}

For eg:
<p>${'John\'s car is "awesome !", Maria said'}</p>

Below special characters are allowed in HTL Strings.
\\ Backslash character
\' Single quote
\" Double quote
\t Tabulation
\n Newline
\r Carriage return
\f Form feed
\b Backspace
\uXXXX (Unicode character specified by the four hexadecimal digits)

Arrays
An array is a collection of values that can be represented with a common name. An array will have an index and order.

Samples:
//Array of 2 elements
${utilityArray[2]}
// Array of 5 digits
${[1,2,3,4,5]}
//print an array by names separated by ':'
${utilityArray.names @ join=':'}

//Dynamically accessing Array
<ul data-sly-list="${utilityArray.names}">
    <li>${ properties[item]}</li>
</ul>

HTL Operators
Logical Operators

Logical Operators are used with Boolean values, where the operator returns the value of one of the specified operands. While using with non-Boolean values, they may return a non-Boolean value. They are of 3 types.
·                AND : <P data-sly-test="${properties.jcr:title && properties.jcr:description}">DISPLAY</p>
·                OR : <P data-sly-test="${properties.jcr:title || properties.jcr:description}">DISPLAY</P>
·                NOT : <p data-sly-test="${!currentPage.hasChild}">DISPLAY</p>

Conditional (ternary) Operator
The conditional operator can be used to define conditions within expressions.

Comparison Operators
Comparison Operators(equality and inequality operators) used to compare identical type operands.
·                Strings - equal - having the same sequence of characters.
·                Numbers - equal having the same value
·                Booleans - equal - when both are true or both are false.
·                Null or undefined variables - equal - to themselves and to each other.
Samples:
<div data-sly-test="${properties.jcr:title == 'true'}">TRUE</div>
<div data-sly-test="${properties.jcr:title != 'true'}">FALSE</div>

<div data-sly-test="${properties['jcr:title'].length > 5}">Title is longer than 5</div>
<div data-sly-test="${properties['jcr:title'].length >= 5}">Title is longer or equal to 5 </div>

<div data-sly-test="${properties['jcr:title'].length > myArray.MAX_LENGTH}">
    Title is longer than the limit of ${myArray.MAX_LENGTH}
</div>

Grouping parentheses
As in other languages, HTL supports bracketing to ensure the preference for operation.
${thirdVar && (firstVar || secondVar)}
HTL Use-API
Use-API provides an easy way of binding logic to the template elements. Use-API's can be written in Java or JavaScript or both. Business logic is written Java, view-specific logic can be written in server-side executed JavaScript.

Sample: Pass in parameters from components.
<div data-sly-use.myClass="${'com.myproject.components.MyTestComponent' @ firstName='John', lastName='Miller'}">
    ${myClass.fullname}
</div>

import com.adobe.cq.sightly.WCMUsePojo;
public class MyTestComponent extends WCMUsePojo {
    // Combine the firstName and lastName
    public String getFullname() {
        return get("firstName", String.class) + " " + get("lastName", String.class);
    }
}
HTL sly-test
<data-sly-test/> Validates and conditionally removes the host element and its content. Returned 'False' removes the element; Returned value 'true' retains the element.
For eg:

<h1 data-sly-test="${display}">text</h1>
Here h1 element and its content will only be rendered if 'display' is true.

Create if-else in HTL.

We can construct if-else by utilizing a data-sly-test. The result of a test can be assigned to a variable. This can be utilized for future validations.
For eg:

<h1 data-sly-test.myVar="${x || y || z}">is true</h1>
<h1 data-sly-test="${!myVar}">Else This</h1>

HTL sly-use
Used to initialize a Java class or JavaScript object. Parameters can be passed to the initialization using options
Java
<div data-sly-use.nav="org.company.Navigation">${nav.foo}</div>
JavaScript
<div data-sly-use.nav="navigation.js">${nav.foo}</div>

HTL sly-unwrap
Trims the html element from the generated markup.
For eg:
<p data-sly-use.sort="sorting.js" data-sly-unwrap>Sort Text</p> will avoid <p> in the output html.

HTL sly-text
Inserts the content of its host element with the specified text by replacing it.
For eg:

<div data-sly-text="${currentPage.title}">My page title</div>. Prints the current page title, still helpful for searching in html source using term 'My Page Title'

HTL sly-attribute

 It helps to add attributes to the host element.
 For eg: 

<div title="Page Title" data-sly-attribute.title="${properties.jcr:title}"></div>
 Prints the current page title, still helpful for searching in html source using term 'Page Title'

HTL sly-element

Used to replaces the element name of the host element of html tags.
For eg:
<h6 data-sly-element="${headerLevel}">Title Text</h6>,
This replaces the h6 with the value of headerLevel. (Say the returned value for 'headerLevel' is 1, the <h6> will be replaced to h1)

HTL sly-repeat
This tag helps to repeat an element multiple times based on the list which is specified.
For eg:

<div data-sly-repeat="${currentPage.listChildren}">${item.name}</div>
The difference with <data-sly-list/> is that list needs a container element where repeat does not require it.

HTL sly-list

The list tag repeats the content of the host element for each enumerable property in the provided object.
For eg:
<h6 data-sly-list="${currentPage.listChildren}">
    <dt>index: ${itemList.index}</dt>
    <dd>value: ${item.title}</dd>
</h6>
Where 'item' is the current item in the iteration & itemList is the object holding the properties.

ItemList Properties:
Property
Description
index:
zero-based counter (0..length-1).
count:
one-based counter (1..length).
first:
true if the current item is the first item.
middle:
true if the current item is neither the first nor the last item.
last:
true if the current item is the last item.
odd:
true if the index is odd.
even:
true if the index is even.

Accessing an HTL list value dynamically,
<h6 data-sly-list.child="${myList}">
    <dt>key: ${child}</dt>
    <dd>value: ${myList[child]}</dd>
</h6>

HTL sly-resource
It helps to include the result of a resource from a path specified. The sling resolution and rendering process will process the indicated resource from the path and the result will be included.

<file data-sly-resource="path/to/myresource"></file>
We can mention various methods for referring resource path. Shown below.
·                "${ @ path='path/to/myresource'}"
·                "${'myresource' @ prependPath='my/path'}"
·                "${'my/path' @ appendPath='myresource'}"

We have also options to modify path using selectors as @ selectors, @ addSelectors, @ removeSelectors

HTL sly-include
Helps to replaces the content of the host element with the markup generated by the specified HTML template file (It can be any of the HTL, JSP, ESP formats.)
For eg:
a JSP Can be included by,
<section data-sly-include="path/to/jsptemplate.jsp"></section>

HTL sly-template
Used to defines a template where the host element and its content are not output by HTL. Always used with <data-sly-call/>
For eg:
<template data-sly-template.mytemplate>TEST</template>
<div data-sly-call="${mytemplate}"></div>

HTL sly-call

Used to call a template defined with <data-sly-template/>. The content of the called template replaces the content of the host element of the call.
For eg:
<template data-sly-template.mytemplate>TEST</template>
<div data-sly-call="${mytemplate}"></div>

HTL Url formatting
HTL allows a rich way of URL Formatting.

HTML Extension
<a href="${item.path @ extension = 'html'}">${item.name}</a>
Adds the html extension to a path.

<a href="${item.path @ extension = 'html', selectors='products'}">${item.name}</a>
Adds the html extension and a selector to a path.

<a href="${item.path @ extension = 'html', fragment=item.name}">${item.name}</a>
Adds the html extension and a fragment (#value) to a path.

HTL Date & Number formatting
The latest AEM versions support numbers and dates formatting which includes timezone and locale formatting. We don't have to write custom code anymore. The syntax for formatting is the format is specified first, then the value which needs to be formatted.

For eg
Date formatting
<h6>${ 'dd-MMMM-yyyy hh:mm:ss' @ format=currentPage.lastModified, timezone='PST', locale='fr'}</h6>

Number formatting 
<h6>${ '#.00' @ format=500}</h6>

HTL request attributes

While using <data-sly-include/> and <data-sly-resource/> it is now easy to pass 'requestAttributes'. These 'requestAttributes' can be accessed or processed in receiving HTL-script.

For eg.
<sly data-sly-use.settings="com.adobe.examples.htl.core.hashmap.Settings" data-sly-include="${ 'productdetails.html' @ requestAttributes=settings.settings}" />

And 'requestAttributes' can be passed from the Java class.

public class Settings extends WCMUsePojo {

  // used to pass is requestAttributes to data-sly-resource
  public Map<String, Object> settings = new HashMap<String, Object>();

  @Override
  public void activate() throws Exception {
    settings.put("order", "ascending");
  }
}

Using requestAttributes using Sling-Model way.

@Model(adaptables=SlingHttpServletRequest.class)
public class ProductSettings {
  @Inject @Optional @Default(values="empty")
  public String order;
}

here 'order' is injected via the Map from the Use-class


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.