The HTML Template Langugae (HTL) JavaScript Use-API enables a HTL file to access helper code written in JavaScript. This allows all complex business logic to be encapsulated in the JavaScript code, while the HTL code deals only with direct markup production.

A Simple Example

We define a component, info, located at

/apps/my-example/components/info

It contains two files:

  • info.js: a JavaScript file that defines the use-class.
  • info.html: an HTL file that defines the component info. This code will use the functionality of info.js through the use-API.

/apps/my-example/component/info/info.js

"use strict";
use(function () {
    var info = {};    
    info.title = granite.resource.properties["title"];
    info.description = granite.resource.properties["description"];    
    return info;
});

/apps/my-example/component/info/info.html

<div data-sly-use.info="info.js">
    <h1>${info.title}</h1>
    <p>${info.description}</p>
</div>

We also create a content node that uses the info component at

/content/my-example, with properties:

  • sling:resourceType = "my-example/component/info"
  • title = "My Example"
  • description = "This is some example content."

Here is the resulting repository structure:

Repository Structure

{
  "apps": {
    "my-example": {
      "components": {
        "info": {
          "info.html": {
            ...
          }, 
          "info.js": {
            ...
          }
        }
      }
    }
 },     
 "content": {
    "my-example": {
      "sling:resourceType": "my-example/component/info",
      "title": "My Example",
      "description": "This is some example content."
    }
  }
}

Consider following component template:

<section class="component-name" data-sly-use.component="component.js">
    <h1>${component.title}</h1>
    <p>${component.description}</p>
</section>

The corresponding logic can be written using following server-side JavaScript, located in a component.js file right next to the template:

use(function () {
    var Constants = {
        DESCRIPTION_PROP: "jcr:description",
        DESCRIPTION_LENGTH: 50
    };
 
    var title = currentPage.getNavigationTitle() || currentPage.getTitle() || currentPage.getName();
    var description = properties.get(Constants.DESCRIPTION_PROP, "").substr(0, Constants.DESCRIPTION_LENGTH);
 
    return {
        title: title,
        description: description
    };
});

This tries to take the title from different sources and crops the description to 50 characters.

Dependencies

Let's imagine that we have a utility class that is already equipped with smart features, like the default logic for the navigation title or nicely cutting a string to a certain length:

use(['../utils/MyUtils.js'], function (utils) {
    var Constants = {
        DESCRIPTION_PROP: "jcr:description",
        DESCRIPTION_LENGTH: 50
    };
 
    var title = utils.getNavigationTitle(currentPage);
    var description = properties.get(Constants.DESCRIPTION_PROP, "").substr(0, Constants.DESCRIPTION_LENGTH);
 
    return {
        title: title,
        description: description
    };
});

Extending

The dependency pattern can also be used to extend the logic of another component (which typically is the sling:resourceSuperType of the current component).

Imagine that the parent component already provides the title, and we want to add a description as well:

use(['../parent-component/parent-component.js'], function (component) {
    var Constants = {
        DESCRIPTION_PROP: "jcr:description",
        DESCRIPTION_LENGTH: 50
    };
 
    component.description = utils.shortenString(properties.get(Constants.DESCRIPTION_PROP, ""), Constants.DESCRIPTION_LENGTH);
 
    return component;
});

Passing Parameters to a Template

In the case of data-sly-template statements that can be independent from components, it can be useful to pass parameters to the associated Use-API.

So in our component let's call a template that is located in a different file:

<section class="component-name" data-sly-use.tmpl="template.html" data-sly-call="${tmpl.templateName @ page=currentPage}"></section>

Then this is the template located in template.html:

<template data-sly-template.templateName="${@ page}" data-sly-use.tmpl="${'template.js' @ page=page, descriptionLength=50}">
    <h1>${tmpl.title}</h1>
    <p>${tmpl.description}</p>
</template>

The corresponding logic can be written using following server-side JavaScript, located in a template.js file right next to the template file:

use(function () {
    var Constants = {
        DESCRIPTION_PROP: "jcr:description"
    };
 
    var title = this.page.getNavigationTitle() || this.page.getTitle() || this.page.getName();
    var description = this.page.getProperties().get(Constants.DESCRIPTION_PROP, "").substr(0, this.descriptionLength);
 
    return {
        title: title,
        description: description
    };
});

The passed parameters are set on the this keyword.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License  Twitter™ and Facebook posts are not covered under the terms of Creative Commons.

Legal Notices   |   Online Privacy Policy