Arti­cle updat­ed on July 27, 2016.

In this arti­cle I want to give you an intro­duc­tion to the HTML Tem­plate Lan­guage (HTL), for­mer­ly known as Sight­ly.

Inter­est­ed in the oth­er parts? Here they are: part 2, part 3, part 4, part 5.

I won’t go much into text, but I want to show you 10 code sam­ples, and com­pare these to the exist­ing way of com­po­nent devel­op­ment via JSP.

The main objec­tives of HTL are:

  • giv­ing back the markup, and not mix­ing it with code
  • every­thing is secure, by default (auto­mat­ic con­text-aware escap­ing)
  • improve the work­flow between the design­er and the devel­op­er

Ready for the first code sam­ple? Here we go!


<div>currentPageName: ${}</div>

Well that looks like a JSP, but not quite. Two main dif­fer­ences:

  • Exten­sion of the file is changed to .html, so in case a design­er wants to look at the file he can just open it in his tools.
  • We have only markup in the file, no inclu­sion of a global.jsp, just markup.


<div data-sly-test="${wcmmode.edit}">Show this only in edit mode to the author</div>

Now it is get­ting more inter­est­ing, we have now a data-sly-test attribute and a wcm­mode object.

When the expres­sion inside data-sly-test eval­u­ates to false the whole tag while be hid­den in the markup.


<div"${wcmmode.edit ||}">
    Show this to the author
<div data-sly-test="${!author}">
    Not in author mode anymore..

data-sly-test also sup­ports the nam­ing and reuse of tests, we have an expres­sion ‘author’ that we want to reuse in oth­er data-sly-test attrib­ut­es.

These are very com­mon use-cas­es and can now be done with­out writ­ing any code are exten­sion.


<div data-sly-text="${currentPage.title}">Mock page title</div>

The data-sly-text attribute will replace the val­ue of the HTML-ele­ment with the expres­sion pro­vid­ed.

In the exam­ple above the page-title will be print­ed. But the mock val­ue can still be in there to make it eas­i­er to view the file in HTML-edi­tors.


<ul data-sly-list.child="${currentPage.listChildren}">

Here you see an exam­ple of a loop, the list object is passed to the data-sly-list attribute. Based on the name (‘child’) you can ref­er­ence each item in the loop.

The out­put is here that see you a list of the sub-pages with all the page-titles.

This is quite a basic list exam­ple, let go to a more advanced one!


<ul data-sly-list.child="${currentPage.listChildren}">
    <li class="${ childList.odd ? 'odd' : 'even'}">${child.title}</li>

In this sam­ple you see a few new ele­ments:

  1. inside a data-sly-list you have access to a list-vari­able that con­tain things like : index, count, odd, even, first, last, mid­dle
  2. in the expres­sion you see the use of the ternary oper­a­tor


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

With data-sly-resource you can include com­po­nents and resources. In the above sam­ple you include of stan­dard para­graph sys­tem in your tem­plate.


<footer data-sly-resource="${'footer' @ resourceType='myproject/footer', wcmmode='disabled'}"></footer>

So you are in need to dis­able the wcm­mode for a spe­cif­ic com­po­nent? That can now be done via the wcm­mode-option when includ­ing a com­po­nent.


${pageProperties.jcr:title || properties.title || "No title"}

With­in an expres­sion you can use the ‘or’ oper­a­tor to define fall­backs in case prop­er­ties are emp­ty. You read the expres­sion from left to right, in the exam­ple here “No title” is shown when jcr:title and properties.title are both emp­ty.


<div data-sly-include="/libs/wcm/core/components/init/init.jsp"></div>

<div data-sly-include="myfile.html"></div>

Via data-sly-include you can include oth­er files like the cq:include tag. From HTL you can still use and re-use JSP files if you want. Like shown here for the author-envi­ron­ment.

In my next arti­cle I will explain more advanced top­ics on how to use your cus­tom Java-class­es with HTL.



Here are the oth­er arti­cles of my intro­duc­tion series:

Oth­er posts on the top­ic:

And here oth­er resources to learn more about it: