Reusing AEM Markup with Sightly and HTL data-sly-call

Adobe Experience Manager projects often accumulate repeated HTML: cards, navigation items, metadata rows, buttons and responsive image treatments appear across many components. Sightly, now known as HTL (HTML Template Language), provides a clean way to reuse that presentation logic without turning templates into difficult-to-maintain scripts.

The data-sly-call block statement is especially useful when a project needs small, focused template functions. It lets a component call a named template, pass structured data into it and keep the resulting markup close to the visual component that owns it. For Australian teams working across Sydney, Melbourne, Brisbane or Perth, this approach can also make reviews and handovers easier across distributed delivery groups.

Approach Best use Strength Common risk
Repeated HTML One-off, unique markup Fast for a prototype Divergent fixes and styling
data-sly-include Shared template fragments Simple file reuse Limited parameter handling
data-sly-resource Rendering AEM resources Preserves component behaviour More runtime overhead
data-sly-template and data-sly-call Reusable parameterised markup Clear inputs and consistent output Poorly designed parameters become confusing

What data-sly-call Does

A reusable HTL template is declared with data-sly-template, then executed with data-sly-call. The declaration defines the parameters, while the call supplies values. A basic example looks like this:

<template data-sly-template.card="${@ title, text, href}">
  <article class="card">
    <h2>${title}</h2>
    <p>${text}</p>
    <a href="${href}">Read more</a>
  </article>
</template>

<div data-sly-call="${card @
  title=model.title,
  text=model.summary,
  href=model.link
}"></div>

The template itself does not print a <template> element into the response. HTL uses the declaration as a server-side rendering instruction and emits the markup generated by the call. This keeps reusable presentation logic declarative and allows HTML escaping to remain part of the normal HTL rendering model.

Parameter names should describe intent rather than implementation. title, summary, image and link communicate more than a generic value object. When a component uses many related fields, passing a model object can be appropriate, but a small template is usually easier to understand when its inputs are explicit.

Keeping Component Markup Consistent

A common pattern is to place shared templates in a component’s HTL file and call them for each item in a list. For example, a navigation template might receive a label, URL, active state and CSS modifier. The parent template controls iteration, while the reusable block controls the exact link structure.

<template data-sly-template.navItem="${@ label, url, active}">
  <li class="${active ? 'is-active' : ''}">
    <a href="${url}" aria-current="${active ? 'page' : ''}">
      ${label}
    </a>
  </li>
</template>

<ul data-sly-list.item="${model.items}">
  <sly data-sly-call="${navItem @
    label=item.label,
    url=item.url,
    active=item.active
  }"></sly>
</ul>

The <sly> element is useful when the call itself should not create an extra wrapper. In other cases, placing data-sly-call on an existing element can make the output easier to read. Review the rendered HTML rather than judging the source template alone, because HTL removes or retains elements according to the block statement used.

This consistency matters for Australian organisations with several brands or regional sites. A Melbourne editorial team may update a component that is also used by a Sydney campaign site, and shared templates reduce the chance that one authoring experience produces different accessibility or tracking markup from another.

Passing Models, Options and Safe Values

HTL templates can accept properties from Sling Models, lists, maps and literal values. A component might pass a model’s image data to a media template while separately supplying a display option:

<sly data-sly-call="${imageTemplate @
  image=model.image,
  loading='lazy',
  decorative=false
}"></sly>

The receiving template can then decide whether to render alternative text, dimensions, a caption or a link. Keep conditional behaviour inside the template when it is intrinsic to the markup. Keep editorial or business decisions in the Sling Model, where Java code can handle data preparation, defaults and validation.

Do not assume that an empty value will behave like a valid value. Define sensible fallbacks for missing titles, links and image paths, and ensure Boolean flags are explicitly interpreted. A malformed URL or absent alt text may be caught during testing but still reach production through an unusual authoring combination.

For public-sector and regulated projects, this discipline supports accessibility obligations under Australia’s Disability Discrimination Act and practical WCAG expectations. A shared link or image template can consistently emit keyboard-friendly structure, useful alternative text and predictable heading order across desktop and mobile layouts.

Choosing Between HTL Reuse Patterns

data-sly-call is best for a parameterised piece of markup that may be rendered several times within a template. It is a good fit for cards, breadcrumbs, tabs, form controls and repeated list items. It keeps the reuse local and makes the data contract visible near the call site.

data-sly-include is more suitable for including a static HTL file when parameter passing is unnecessary. data-sly-resource is valuable when AEM should resolve and render another resource through its component system, including selectors and resource type behaviour. These mechanisms solve different problems, so replacing every include with a template call can make an implementation less clear.

Avoid using template calls to hide large business rules. HTL should present prepared data, not become a substitute for Java services or Sling Models. If a call requires a dozen flags and nested objects, the abstraction may be too broad. Split the visual pattern or prepare a purpose-built view model instead.

Debugging Rendering and Deployment

When a reused block appears empty, inspect the parameter expression first. A typo in model.summary, an incorrect map key or an unexpected null value can produce valid-looking output with missing content. AEM’s developer tools, repository inspection and rendered HTML are more reliable than examining only the authoring dialog.

Caching can make a correct HTL change appear ineffective. Clear the relevant dispatcher or CDN cache, check the publish instance and confirm that the client library and component version are deployed together. Teams supporting customers across Australia should account for multiple publish regions and release windows, especially when Sydney and Perth teams are testing against different environments.

Content replication problems can also be mistaken for template failures. Before changing HTL, review replication troubleshooting steps to confirm that the page, referenced assets and policies have reached the expected publish tier. A template cannot render content that has not been activated or is blocked by permissions.

Integrating Reusable Markup with Search and Analytics

Reusable templates are valuable at the boundary between content and platform integrations. A search result card, for instance, can receive a title, excerpt, URL, content type and highlighted terms from a search service while keeping its HTML consistent with ordinary site cards. This creates a stable rendering contract even when the backing query changes.

When AEM uses Elasticsearch or another external index, decide which fields are prepared by the service and which are formatted in HTL. Search ranking, filtering and highlighting belong outside the template; link structure, escaping and accessible labels belong in the presentation layer. The guidance on AEM Elasticsearch search can help frame that separation.

Analytics attributes also benefit from one shared template. A card or navigation item can consistently emit an event name, content identifier and destination category without every component author inventing its own data attributes. Avoid exposing private customer information in tracking values, particularly when Australian Privacy Act obligations apply to personal data and behavioural records.

Practical Recommendations for HTL Templates

  • Give every reusable template a narrow purpose and a small, documented parameter set.
  • Prefer Sling Models for data preparation, validation and fallback values.
  • Use explicit parameter names such as label, href, image and isActive.
  • Inspect published HTML for accessibility, escaping, empty states and unwanted wrapper elements.
  • Test calls with missing values, long Australian place names and mobile layouts.
  • Keep search, analytics and business rules outside the presentation template.
  • Include template rendering, cache invalidation and replication checks in deployment testing.

A well-designed data-sly-call pattern makes AEM markup easier to extend without sacrificing output quality. Start with one repeated component, define its data contract, compare the rendered HTML before and after refactoring, then apply the same discipline to navigation, search results and content cards. Teams can review the change in source control, validate it on an Australian publish environment and carry the pattern into future AEM components with far less duplication.