HomeFrontend Development › HTL deep dive

HTL deep dive

Purpose: Full working reference for HTL: blocks, expression options, contexts, and template/call reuse.

Who this page is for

AudienceWhy it matters to you
Frontend engineersDaily reference

Block statements

StatementPurposeNote
data-sly-useBind a model/template/JS use-objectdata-sly-use.m="…PlanCardModel"
data-sly-testConditional renderStore result: data-sly-test.hasPlans="…" reuses it
data-sly-list / data-sly-repeatIterate (list wraps, repeat repeats the element)itemList.index/first/last
data-sly-resourceInclude another resource/componentThe composition primitive
data-sly-includeInclude another script (same context)Script split, not component include
data-sly-template / data-sly-callDefine/call a markup functionParameterised partials
data-sly-attributeSet attributes from a mapDrops empty attributes safely
data-sly-elementChange the element tag name
data-sly-unwrapRender children without the wrapper elementPrefer <sly> element

Expression options

${model.title @ context='text'}            escaping context (see below)
${model.ctaPath @ extension='html'}       proper link building
${'page.label' @ i18n}                    translation
${model.items @ join=', '}                list join
${properties.date @ format='dd MMM yyyy', locale=request.locale}

Contexts (XSS protection)

HTL escapes per context — the reason "just render it" is safe by default:

ContextUse for
text (default in body)Visible text
attribute (default in attrs)Attribute values
urihref/src — rejects javascript: etc.
htmlRich text from RTE — sanitises markup
scriptToken/styleToken etc.Rare, deliberate cases
unsafeDisables protection — requires security review, almost never justified

Rich text pattern: ${model.disclaimerHtml @ context='html'} — sanitised, tags preserved.

Template reuse

<template data-sly-template.benefitRow="${@ benefit}">
  <li class="${benefit.covered ? 'tick' : 'cross'}">${benefit.label}</li>
</template>
<ul data-sly-list.b="${model.benefits}">
  <sly data-sly-call="${benefitRow @ benefit=b}"></sly>
</ul>

Shared template libraries: put templates in a common file and data-sly-use it from any component.

Quick navigation