Skip to content

Foundations

Writing HTL

HTL (the HTML Template Language) is Apache Sling’s server-side templating language. In Kestros it is the language you write component views in: the HTML that renders a component. HTL stays close to plain HTML, so a view file reads like markup with a few extra attributes and expressions.

This page is a short introduction, not an HTL reference. HTL is defined and maintained by Apache Sling, and the Sling documentation is the authoritative, complete specification of the language. This page explains where HTL fits in Kestros and gives a small taste of the syntax so you can read a component view; for anything beyond that, follow the Sling reference linked below.

What HTL is

HTL is the templating language Apache Sling uses to turn a resource and its script into rendered HTML. It was designed to stay valid, readable HTML: logic lives in data-sly-* attributes on ordinary elements and in ${ ... } expressions inside the markup, rather than in a separate scripting syntax embedded in the page.

A component’s markup comes from its HTL file: Sling evaluates the script against the resource being rendered and writes the result into the page. See the Glossary for how the surrounding terms (component, component view, resource) fit together.

HTL in component views

A component view is an HTL file. The main view a component renders is named content.html. When the component renders, Sling evaluates that file against the current resource and writes the resulting HTML into the page. A minimal view is just markup with an expression or two:

content.html
<div class="teaser">
  <h2>${properties.title}</h2>

  <p data-sly-test="${properties.summary}">
    ${properties.summary}
  </p>
</div>

Real views combine these statements. Below is the default layout of the Kestros card-list component, unedited. It binds a Java model, loops over the cards that model exposes, and lets Sling render each card through its own view:

The terms component, component view, and datasource are defined in the Glossary and covered in later pages; here just read the HTL statements and note what each one does.
card-list / layouts / default / content.html
<sly data-sly-use.cardList="${'io.kestros.cms.components.basic.core.lists.cardlist.CardListDataSourceComponent'}"/>
<div class="row row-cols-1 row-cols-md-3 ${cardList.inlineVariations}">
    <sly data-sly-list.card="${cardList.cards}">
        <div class="col mb-4">
            <sly data-sly-resource="${card}"/>
        </div>
    </sly>
</div>
  • data-sly-use.cardList binds the Java model class and names it cardList, so the rest of the file can read from it.
  • data-sly-list.card repeats its block once per item in cardList.cards, exposing each item as card.
  • data-sly-resource="${card}" hands each card back to Sling, which renders it through its own component view (the list does not know or care what a card looks like).
  • <sly> carries HTL statements without adding an element to the output, so only the <div> wrappers reach the page.

A taste of the language

The list below is orientation only, so the snippet above and the view files you read make sense. It is not the full language and it deliberately avoids details; treat the Sling reference as the source of truth for exact behavior.

  • ${ ... } is an expression: it outputs a value into the markup.
  • data-sly-use makes an object (such as a model) available to the template.
  • data-sly-resource includes another resource, rendering its own view in place.
  • data-sly-list repeats an element over a collection.
  • data-sly-test conditionally keeps or drops an element based on an expression.
Each of these has options, escaping and context rules, and additional block statements not listed here. Read them in the Sling documentation before relying on any specific behavior.

The authoritative reference

HTL is an Apache Sling technology. Its specification, the full set of block statements, expression options, and escaping rules live in the Sling HTL scripting documentation. When you need to know what HTL does, go there: