Sightly | HTL(HTML Template Language)
HTL (Previously known as Sightly) was first
introduced in AEM 6.0 as an alternate of JSP, EcmaScript & JSLT.
Now it is preferred templating language
in AEM. It is recommended for new AEM projects to use HTL as it offers
multiple benefits compared to JSP.
Although languages like of JSP (Java
Server pages) and ESP (ECMA Script Server Pages) serve well for website
development in AEM, HTL is emerging to be a preferred templating language
for HTML because, HTML developers can participate better in AEM project without
any JAVA knowledge.
Advantages of using HTL:-
· New
AEM developers have shorter learning curve
· Easy
to maintain project with cleaner code
· Elimination
of UI/AEM integration issues
· Increased
developer productivity
· Secure:
URL Externalization and XSS Protection
· Finally
helps you forget about JSP Scriptlets, with embedded business logic.
· Offers
pure view and help move the business logic to Java classes (externalizing the
business logic)
· Addresses
problems in AEM such as lack of separation of concerns
· HTL only Supports HTML5.
· Using
HTL components development becomes a part of Web Developer instead of a
java developer.
· Wider range
of implicit objects as compared to JSP.
HTL shows its significance in enabling Java developers to
focus on the backend code independently. This specific feature distinguishes
HTL from other templating systems where Java developers should have little
front-end knowledge for integration. Therefore, HTL often reduces
coordination issues, as the frontend development might not be a primary skill
for every Java developer.
Features of HTL listed here:
Secure:- The
HTL increases the security of sites that use it in their implementation, as
compared to JSP and to most other template systems, because HTL is capable of
automatically applying the proper context-aware escaping to all variables being
output to the presentation layer. HTL makes this possible because it
understands the HTML syntax, and uses that knowledge to adjust the required
escaping for expressions, based on their position in the markup.
Eg.
<p style="${colorText? 'color:red' :
'color:grey'}">${text}</p>
Looks pretty nice, but doesn’t work, as HTL recognizes the CSS style and removes it as potentially harmful content. Add
the context like
this, saying ‘I actually want to deliver style information here’:
<p style="${ colorText? 'color:red' :
'color:grey' @ context='styleToken'}">${text}</p>
Separation of concerns:- Separation
of concerns defines the separation of the frontend from the business logic in
different files. Initially, business would require writing all templates in
JSTL, because JSP logic tends to sneak into the views. Another disadvantage is,
JSTL can become rather unwieldy and produce lots of clutter. This was very much
reduced in HTL and it helps bridge the gap between back end as well as
front end development. In JSP you mix markup with Java code using
scriptlet but in HTL it’s purely mark up and Java code resides in bundles
Reduced Costs - Increased security, simplified development and
improved team collaboration, translates for AEM projects in reduced effort,
faster time to market (TTM), and lower total cost of ownership (TCO).
Integrations with sling models:-
HTL does not require Sling models, there are different ways to get your logic into
HTL. Still, the sling models are considered as the perfect way to set the
Java logic up.
Templates-Define reusable:-
In HTL, Templates
tend to define re-usable and potentially recursive methods that can be defined
locally or in separate files.
Localizing Terms:-
HTL localize
terms provided in dictionaries in an easy and beautiful manner by just adding
the context i18n.
Simplified Development: - The HTML Template Language is easy to learn and its features are purposely limited to ensure that it stays simple and straight-forward.
Simplified Development: - The HTML Template Language is easy to learn and its features are purposely limited to ensure that it stays simple and straight-forward.
In conclusion,
HTL templating engine is a powerful, versatile tool with many benefits for
web development in AEM platforms. Additionally, it improves time-to market and
reduces the Total Cost of Ownership of Your AEM 6.x projects. It also
helps in introducing a clean separation of concerns and prevents developers from
writing business logic and the markup, thus reduces the load time of the
webpage.
Difference between Sightly and JSP:-
Sightly Offers below advantages over JSP for better development in AEM
- Protection against cross-side scripting injection.
- Easily development of AEM Projects by front-end developers.
- Flexible and powerful templating and logic binding features
- Need to write less code in Sightly thus productivity increases.
- Wider range of implicit objects as compared to JSP.
HTL Block Statements:-
1:- data-sly-use statement:-
Initializes a helper object (defined in JavaScript or Java) and exposes it through a variable.
1: HTL Component with Java:-
Initialize a Java class, where the source file is located in the same directory as the template. Note that the classname must be used, not the file name:
<div data-sly-use.nav="Navigation">${nav.foo}</div>
Initialize a Java class, where that class is installed as part of an OSGi bundle. Note that its fully-qualified class name must be used:
<div data-sly-use.nav="org.example.Navigation">${nav.foo}</div>
<div id="my-component"
data-sly-use.mycomponent="com.test.wcm.view.helper.MyComponentViewHelper">
<h1>${mycomponent.title}</h1>
<p>${mycomponent.description}</p>
</div>
· Java
File (Can be put inside component or can be part of bundle):
package com.test.wcm.view.helper;
import
com.adobe.cq.sightly.WCMUsePojo;
public class MyComponentViewHelper
extends WCMUsePojo {
private String title;
private String description;
@Override
public void activate() throws Exception {
title =
getProperties().get("title", "DEFAULT_TITLE");
description =
getProperties().get("description", "DEFAULT_DESCRIPTION");
}
// Must have to get
back the value in html file
// Explanation :
'get' + capitalize method name
public String getTitle() {
return title;
}
public String
getDescription() {
return description;
}
}
2: HTL Component with server side JavaScript:-
Initialize a JavaScript object, where the source file is located in the same directory as the template. Note that the filename must be used:
<div data-sly-use.nav="navigation.js">${nav.foo}</div>
· Server
Side Java script file(mycomponent.js file in your component folder):-
use(function () {
var title = currentPage.getTitle();
var description = properties.get("jcr:description",
"default desc");
return {
title: title,
description: description
};
});
· HTML
File:-
<div id="my-component"
data-sly-use.mycomponent="mycomponent.js">
<h1>${mycomponent.title}</h1>
<p>${mycomponent.description}</p>
</div>
We can Java Class or
Javascript Server-Side File. Mostly we use Java Class as AEM Java API offer more functionalities than
Javascript API.
Example:
Output:
Explanation:
{properties. isValid } is some statement which evaluates to true. Hence displayed.
data-sly-resource statement:-
Output:
2: Overriding the resourceType:
3: Changing the WCM mode on the fly as required:
Output:
So as we can see the above template.html gets defined similar to a method/function in JAVA.
File: Caller.html
Ouput:
In short the Template Statement is used to define a method/function.
The Call Statement is used to call the defined method.
data-sly-unwrap statement:-
Removes the host HTML element while retaining its
content.
Example:
<div
data-sly-unwrap>Hello World</div>
Output: Hello World
It is also possible to conditionally unwrap an element:
<div class="popup" data-sly-unwrap="${isPopup}">content</div>
sly element:-
sly element:-
<sly> element does not get displayed in the resulting HTML and can be used instead of the data-sly-unwrap. The goal of the <sly> element is to make it more obvious that the element is not outputted. If you want you can still use data-sly-unwrap.
<sly data-sly-test.varone="${properties.yourProp}"/>
data-sly-test statement:-
Test a
statement and if condition is false then removes the element
and its contents.
Example:
Example:
<p
data-sly-test="${properties.isValid}">This is valid</p>
Output:
<p>This is valid</p>
Explanation:
{properties. isValid } is some statement which evaluates to true. Hence displayed.
The result of a test can be assigned to a variable that can be used later. This is usually used to construct "if else" logic, since there is no explicit else statement:
<p data-sly-test.abc="${a || b || c}">is true</p> <p data-sly-test="${!abc}">or not</p>
The variable, once set, has global scope within the HTL file.
Following are some examples on comparing values:
<div data-sly-test="${properties.jcr:title == 'test'}">TEST</div> <div data-sly-test="${properties.jcr:title != 'test'}">NOT TEST</div> <div data-sly-test="${properties['jcr:title'].length > 3}">Title is longer than 3</div> <div data-sly-test="${properties['jcr:title'].length >= 0}">Title is longer or equal to zero </div> <div data-sly-test="${properties['jcr:title'].length > aemComponent.MAX_LENGTH}"> Title is longer than the limit of ${aemComponent.MAX_LENGTH} </div>
data-sly-list statement:-
: The current item in the iteration.
: Object holding the following properties:
: zero-based counter (
: one-based counter (
:
:
:
:
Repeats the content of the host element for each enumerable property in the provided object.
Here is a simple loop:
<dl data-sly-list="${currentPage.listChildren}"> <dt>index: ${itemList.index}</dt> <dd>value: ${item.title}</dd> </dl>
The following default variables are available within the scope of the list:
item
itemList
index
0..length-1
).
count
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
index
is odd.
even
true
if
index
is even.
Defining an identifier on the
and
will become ***
will become
.
data-sly-list
statement allows you to rename the
itemList
item
variables.
item
<variable>
*** and
itemList
*<variable>*List
<dl data-sly-list.child="${currentPage.listChildren}"> <dt>index: ${childList.index}</dt> <dd>value: ${child.title}</dd> </dl>
You can also access properties dynamically:
<dl data-sly-list.child="${myObj}"> <dt>key: ${child}</dt> <dd>value: ${myObj[child]}</dd> </dl>
data-sly-repeat statement:-
This tag helps to repeat an element multiple times based on the list which is specified.
<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.
This tag helps to repeat an element multiple times based on the list which is specified.
<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.
data-sly-repeat
repeats the whole element that is marked, while data-sly-list
only repeats the content of the element.data-sly-resource statement:-
Includes the
indicated resource.
Example:1
<sly
data-sly-resource="path/to/resource"></sly>
Output:
<sly><!-- Result of
the rendered resource --></sly>
Example:2
<!-- /* Include the
component image */ !-->
<div
data-sly-resource="${'image' @
resourceType='wcm/foundation/components/image'}"></div>
1: Resource Statement Options
You can
specify, add or remove selectors like the following.
Example:
Example:
<article
data-sly-resource="${'path/to/resource' @
selectors='mobile'}"></article>
2: Overriding the resourceType:
<article
data-sly-resource="${'path/to/resource' @
resourceType='my/resource/type'}"></article>
3: Changing the WCM mode on the fly as required:
<article data-sly-resource="${'path/to/resource'
@
wcmmode='disabled'}"></article>
****Include Statement(data-sly-include)****
Includes
the rendering of the indicated template (Sightly, JSP, ESP, etc.)
Example:
Example:
<section
data-sly-include="path/to/template.html"></section>
Output:
<section><!-- Result of
the rendered resource --></section>
***Attribute
Statement (data-sly-attribute)***
Adds HTML attributes to the host
element.
Example:1
<div
data-sly-attribute.class="${properties.myClass}"></div>
Output:
<div
class="colorRed"></div>
Example:2 With a map of
attributes
attributes = {
title:
"beautiful title",
class:
"testClass",
}
<div
data-sly-attribute="${attributes}"></div>
Output:
<div title="beautiful
title" class="testClass"></div>
***Template & Call Statement(data-sly-template
& data-sly-call)***
These are the HTML blocks which act a function. Every blocks will have an identifier and like normal function they do accept parameters. When you are defining the block, you can define all parameters that will be accepted by it..
Example
of template:
File: template.html
File: template.html
<template
data-sly-template.testUtility="${@ name, title}">
<span
class="${name}">${title}</span>
</template>
So as we can see the above template.html gets defined similar to a method/function in JAVA.
File: Caller.html
<div
data-sly-use.tmpl="template.html"
data-sly-call="${tmpl.testUtility@ name='Saurabh',
title='Kumar'}"></div>
Ouput:
<div><span
class="Saurabh">Kumar</span></div>
In short the Template Statement is used to define a method/function.
The Call Statement is used to call the defined method.
How to add client library on page in HTL:
!--/* Do not forget the
data-sly-use ! */-->
<div
data-sly-use.clientLib="${'/libs/granite/sightly/templates/clientlib.html'}">
<div data-sly-call="${clientLib.css @
categories='comp1'}" data-sly-unwrap/></div>
<div data-sly-call="${clientLib.js @
categories='comp12'}" data-sly-unwrap/></div>
<div data-sly-call="${clientLib.all @
categories=['comp1', 'comp2']}"
data-sly-unwrap/></div>
</div>
What are the implicit object present in sightly?
HTL provides access to all objects that were commonly available in JSP after including
global.jsp
Enumerable Objects
These objects provide convenient access to commonly used information. Their content can be accessed with the dot notation, and they can be iterated-through using
data-sly-list or data-sly-repeat
.
Java-backed Objects
Each of the following objects is backed by the corresponding Java object.
The most useful variables in the table below are highlighted in bold.
Variable Name
|
Description
| |
---|---|---|
component
|
com.day.cq.wcm.api.components.Component
| |
componentContext
|
com.day.cq.wcm.api.components.ComponentContext
| |
currentDesign
|
com.day.cq.wcm.api.designer.Design
| |
currentNode
|
javax.jcr.Node
| |
currentPage
|
com.day.cq.wcm.api.Page
| |
currentSession
|
javax.servlet.http.HttpSession
| |
currentStyle
|
com.day.cq.wcm.api.designer.Style
| |
designer
|
com.day.cq.wcm.api.designer.Designer
| |
editContext
|
com.day.cq.wcm.api.components.EditContext
| |
log
|
org.slf4j.Logger
| |
out
|
java.io.PrintWriter
| |
pageManager
|
com.day.cq.wcm.api.PageManager
| |
reader
|
java.io.BufferedReader
| |
request
|
org.apache.sling.api.SlingHttpServletRequest
| |
resolver
|
org.apache.sling.api.resource.ResourceResolver
| |
resource
|
org.apache.sling.api.resource.Resource
| |
resourceDesign
|
com.day.cq.wcm.api.designer.Design
| |
resourcePage
|
com.day.cq.wcm.api.Page
| |
response
|
org.apache.sling.api.SlingHttpServletResponse
| |
sling
|
org.apache.sling.api.scripting.SlingScriptHelper
| |
slyWcmHelper
|
com.adobe.cq.sightly.WCMScriptHelper
| |
wcmmode
|
com.adobe.cq.sightly.SightlyWCMMode
| |
xssAPI
|
com.adobe.granite.xss.XSSAPI
|
Comments
Post a Comment