Skip to content

HTL Style Guide

Richard Hand edited this page Jun 13, 2019 · 22 revisions

Style guide for HTL, the HTML templating language used in the Adobe Experience Manager Core Components.

Contents

Comments

Prefer HTL Comments Over HTML Comments

HTML comments are rendered in the final markup, so unless there is a specific need, HTL comments are always preferred.

<!-- Don't use HTML comments -->

<!--/* Do use HTL comments */-->

↑ Back to top

Block Statements

Style guide for HTL Block Statements.

Use the sly Tag for All Elements That Are Not Part of the Markup

<!--/* Instead of */-->
<div data-sly-include="content.html" data-sly-unwrap></div>
 
<!--/* Use */-->
<sly data-sly-include="content.html"></sly>
<!--/* Instead of */-->
<div data-sly-resource="${item @ selectors='event'}" data-sly-unwrap></div>
 
<!--/* Use */-->
<sly data-sly-resource="${item @ selectors = 'event'}"></sly>
<!--/* Instead of */-->
<div data-sly-test="${event.hasDate}" data-sly-unwrap>
    ...
</div>
 
<!--/* Use */-->
<sly data-sly-test="${event.hasDate}">
    ...
</sly>

Don't Use sly Elements Unless Necessary

<!--/* Instead of */-->
<sly data-sly-test.title="${component.title}">
  <h1>${title}</h1>
</sly>

<!--/* Use */-->
<h1 data-sly-test.title="${component.title}">${title}</h1>

Don't Use a Self-closing sly Element

Rather than <sly/>, use <sly></sly>, as the sly element is neither a void nor foreign element. See html5 start tags.

Prefer data-sly-repeat Over data-sly-list

Use data-sly-repeat over data-sly-list, in order to avoid creating unnecessary sly tags.

<!--/* Instead of */-->
<sly data-sly-list.child="${container.children}">
  <div data-sly-resource="${child}"></div>
</sly>
 
<!--/* Use */-->
<div data-sly-repeat.child="${container.children}" data-sly-resource="${child}"></div>

Re-use data-sly-test Variables

If a data-sly-test is used multiple times, define a variable and re-use it, for performance reasons.

<!--/* Instead of */-->
<h1 data-sly-test="${component.textEnabled}">${component.title}</h1>
    ...
<p data-sly-test="${component.textEnabled}">${component.description}<p>

<!--/* Use */-->
<h1 data-sly-test.textEnabled="${component.textEnabled}">${component.title}</h1>
   ...
<p data-sly-test="${textEnabled}">${component.description}<p>

Place HTL Block Statements Before Regular HTML Attributes

Defining HTL block statements first means that variables are available for use in the regular HTML attributes, and that block statements (particularly data-sly-test, data-sly-list and data-sly-repeat) statements are prominent.

<!--/* Instead of */-->
<h1 class="cmp-component__title" data-sly-test="${component.title}">${component.title}</h1>

<!--/* Use */-->
<h1 data-sly-test="${component.title}" class="cmp-component__title">${component.title}</h1>

Place Use Data-sly-use Statements On Top-level Elements

Since data-sly-use identifiers are always global, the data-sly-use attribute should be placed on top-level elements - making it easier to see name clashes and preventing multiple initialization of same Object.

<!--/* Instead of */-->
<div class="cmp-teaser">
   <h3 data-sly-use.teaser="com.example.models.Teaser">${teaser.title}</h3>
</div>

<!--/* Use */-->
<div data-sly-use.teaser="com.example.models.Teaser" class="cmp-teaser">
   <h3>${teaser.title}</h3>
</div>

Use Meaningful Identifier Names

To improve readability, use meaningful identifier names. Fullwords rather than shorthands or acronyms are preferred.

<!--/* Instead of */-->
<sly data-sly-use.comp="com.example.models.Teaser">
    ...
</sly>
 
<!--/* Use */-->
<sly data-sly-use.teaser="com.example.models.Teaser">
    ...
</sly>
<!--/* Instead of */-->
<sly data-sly-use.bc="com.example.models.breadcrumb">
    ...
</sly>
 
<!--/* Use */-->
<sly data-sly-use.breadcrumb="com.example.models.Breadcrumb">
    ...
</sly>

Use lowerCamelCase for Identifier Names

<!--/* Instead of */-->
<sly data-sly-use.languagenavigation="com.example.models.LanguageNavigation">
    ...
</sly>
 
<!--/* Use */-->
<sly data-sly-use.languageNavigation="com.example.models.LanguageNavigation">
    ...
</sly>

Avoid the Element, Attribute and Text Block Statements

Usually these block statements can be avoided, leading to cleaner, more easily read code.

<!--/* Instead of */-->
<div data-sly-element="${teaser.titleElement}">${teaser.title}</div>
<a data-sly-attribute.href="${teaser.link}" href="#"></a>
<p data-sly-text="${teaser.description}"></p>
 
<!--/* Use */-->
<h2>${teaser.title}</h2>
<a href="${teaser.link}"></a>
<p>${teaser.description}</p>

↑ Back to top

Expression Language

Style Guide for HTL Expression Language.

Simplify String Expressions Involving the Ternary Operator

<!--/* Instead of */-->
<div class="${cssClass ? cssClass : 'my-class'}"></div>

<!--/* Use */-->
<div class="${cssClass || 'my-class'}"></div>

Only Set a Display Context If Necessary

In most cases the display context can be left out as it is determined automatically.

<!--/* Instead of */-->
<a href="${component.link @ context = 'uri'}"></a>

<!--/* Use */-->
<a href="${component.link}"></a>

Prefer the Extension Option for URLs Over a Hardcoded Extension

See HTL URL Manipulation.

<!--/* Instead of */-->
<a href="${component.link}.html"></a>

<!--/* Use */-->
<a href="${component.link @ extension = 'html'}"></a>

Drop Method Prefixes When Accessing Properties from Java Getter Functions

Java getter functions such as getTitle() or isActive() can be accessed without the get or is prefixes and lowering the case of the following character. All properties should be accessed this way for consistency and readability.

<!--/* Instead of */-->
<p>${component.getTitle}</p>

<!--/* Use */-->
<p>${component.title}</p>
<!--/* Instead of */-->
<a href="${item.link}" data-sly-unwrap="${item.isActive}">...</a>

<!--/* Use */-->
<a href="${item.link}" data-sly-unwrap="${item.active}">...</a>

Don't Write Unnecessary Expressions for Literals

<!--/* Instead of */-->
<sly data-sly-use.clientlib="${'/libs/granite/sightly/templates/clientlib.html'}">
    ...
</sly>

<!--/* Use */-->
<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html">
    ...
</sly>

↑ Back to top