HTL (formerly Sightly) is AEM's server-side template language. It completely replaces JSP and serves as the standard for rendering components. HTL'
HTL Templates
HTL (HTML Template Language) in AEM
HTL (formerly Sightly) is AEM's server-side template language. It completely replaces JSP and serves as the standard for rendering components. HTL's core philosophy is secure by default — automatically escaping output data to prevent XSS attacks.
1. Expressions
Expressions print values to HTML using $\{\} syntax:
1.1. Expression Options
Modify how data is rendered by adding @ following the variable:
1.2. Display Contexts
Although HTL chooses security context automatically, you can (and sometimes must) override it. Common contexts include:
Security Warning: NEVER use
context='unsafe'unless completely certain content is safe. For Rich Text Editor (RTE) output, RTE sanitizes malicious code on save, and defaulthtmlcontext provides extra protection on render. RTE output called via$\{model.richText\}is safe!
2. Block Statements
Block statements are HTML attributes prefixed with data-sly-. They control HTL logic execution.
2.1. data-sly-use (Initialize Model)
Loads a Sling Model or template file into a variable.
(Variable identifier follows dot — e.g. .model — used in HTL).
2.2. data-sly-test (Conditional Rendering)
Functions like an if statement. Can also be used for variable assignment.
Note: Values evaluated as false: null, empty string "", number 0, boolean false, and empty collections/arrays.
2.3. data-sly-list vs data-sly-repeat (Loops)
Both iterate over arrays/collections, but impact DOM structure differently.
Loop Helper Variable (itemList): Inside loops, HTL automatically generates itemList object with properties:
2.4. data-sly-resource vs data-sly-include
Embeds another component or HTML file into current template.
-
data-sly-resource: Embeds a component. Triggers Sling Resolution (invokes Java logic, loads child component Dialog). -
data-sly-include: Includes a static HTML snippet directly. Does NOT trigger Sling Resolution.
2.5. data-sly-template / data-sly-call (UI Reuse)
Defines an HTML block as a function and calls it in multiple places.
2.6. data-sly-element (Dynamic HTML Tag)
Dynamically changes HTML element based on configuration.
2.7. data-sly-attribute (HTML Attributes)
2.8. data-sly-text (Override Text)
Retains mockup text for frontend design time, automatically replaced when rendered.
2.9. data-sly-unwrap (Remove Wrapper Tag)
Keeps inner content while unwrapping host HTML tag from DOM. Useful for logical wrappers without introducing unnecessary wrapper <div/> elements.
2.10. data-sly-set (Local Variable Assignment)
Introduced in HTL 1.4, assigns calculated values to local variables without creating HTML tags.
3. Global Objects
HTL templates automatically inject global objects:
Practical Example:
4. The Use API
3 ways to connect HTL with Backend Logic:
Level 1: Call Sling Model Directly (Recommended)
Standard approach for 99% of components.
Level 2: Call Sling Model with Parameters
Pass parameters from HTL to Java model.
HTL Template:
Java Sling Model:
Level 3: Use Javascript Use Objects (Deprecated)
Server-side JS files. Deprecated on AEM as a Cloud Service (AEMaaCS). Always use Sling Models.
5. Practical Example: Article Card Component
6. HTL Best Practices
- Always Use Sling Models: Keep complex logic in Java; HTL should only handle UI rendering.
- Never Use
context='unsafe': Unless fully aware of security implications. - Keep Templates Simple: If conditional statements become complex, move logic to Java.
- Use Template & Call: Split UI into reusable fragments (
data-sly-template/data-sly-call). - Follow BEM Naming: Use
cmp-prefix for CSS classes to align with Core Components standards. - Provide Placeholders: Use
wcmmode.editto show placeholder messages when component is unconfigured. - Guard with
data-sly-test: Check variables fornullbefore rendering markup.