Arti­cle updat­ed on July 27, 2016.

Here are some exam­ples on how you can use the JavaScript Use-API with the HTML Tem­plate Lan­guage (HTL), for­mer­ly known as Sight­ly. If you’re new to the lan­guage, I’d rec­om­mend that you also have a look that the get­ting start­ed guide for HTL.

Hello World

Let’s start with the “Hel­lo World” exam­ple, to get a basic idea how the Use-API works.

I have this in the .html file of my com­po­nent:

<div data-sly-use.logic="logic.js">
    ${logic.hello}
</div>

And this is my logic.js:

use(function () {
    var message = "Hello World";

    return {
        // anything exposed here can be used inside your template
        hello: message
    };
});

I hope this exam­ple is quite self-explana­to­ry. First, the data-sly-use attribute exe­cutes the con­tent of the “logic.js” file and makes the result avail­able in a vari­able named “log­ic”. Then, the “logic.js” file pro­vides a func­tion that returns an object with a prop­er­ty named “hel­lo”.

Note that all of this is exe­cut­ed serv­er-side, and the result sent to the client is the markup with­out any data-sly- argu­ments.

Using predefined objects

Here now an exam­ple on how to use pre­de­fined objects with­in your JS file. In this sam­ple I am sim­ply out­putting some val­ues in order to show you how to use the pre­de­fined objects.

This is in my HTL com­po­nent:

<div data-sly-use.predefined="predefined.js">
    <p>${predefined.pageName}</p>
    <p>${predefined.title}</p>
    <p>${predefined.resourceName}</p>
    <p>${predefined.resourceTitle}</p>
</div>

This is my predefined.js file:

use(function () {
    var pageName = currentPage.name;
    var title = currentPage.properties.get("jcr:title");
    var resourceName = granite.resource.name;
    var resourceTitle = properties.get("jcr:title");

    return {
        pageName: pageName,
        title: title,
        resourceName: resourceName,
        resourceTitle: resourceTitle
    };
});

Passing parameters to the JavaScript Use-API

In this exam­ple I will pass on some para­me­ters to the JS file.

This is my HTL com­po­nent:

<div data-sly-use.params="${'params.js' @ value1='feike', value2='visser', seperator=' '}">
    ${params.newValue}
</div>

Please note the ${‘ ’} nota­tion used to define the Use-API that is called: using an HTL expres­sion allows to spec­i­fy options (every­thing that fol­lows the “@” sym­bol), which will be passed as para­me­ters to the Use-API.

This is in my HTL JavaScript log­ic file “params.js”:

use(function () {
    // you can reference the parameters via the this keyword.
    var retValue = this.value1 + this.seperator + this.value2;

    return {
        newValue: retValue
    };
});

Passing objects to HTL templates

In HTL, it is pos­si­ble to iso­late pieces of markup in tem­plates, and to call them in a sim­i­lar fash­ion with data-sly-call. In this exam­ple, I will cre­ate a tem­plate to list the chil­dren of the pro­vid­ed page object. Strict­ly speak­ing, this isn’t relat­ed to the JS Use-API but it intro­duces the data-sly-tem­plate fea­ture that is nec­es­sary to under­stand for the next sec­tion.

This is the .html file of my com­po­nent:

<h2>Child Pages</h2>
<div data-sly-use.template="templates.html"
     data-sly-call="${template.pageChildren @ parent=currentPage}"></div>

I can then have a templates.html file with com­mon­ly reused tem­plates, like fol­low­ing one:

<sly data-sly-template.pageChildren="${@ parent}">
    <ul data-sly-list="${parent.listChildren}">
        <li>${item.title}</li>
    </ul>
</sly>

This is how it works:

  • The com­po­nent first ini­tial­izes the “templates.html” file with data-sly-use, which makes it avail­able as a “tem­plate” vari­able. This also makes all con­tained data-sly-tem­plate blocks avail­able as prop­er­ties of that “tem­plate” vari­able.
  • With data-sly-call, I can then exe­cute my tem­plate, plac­ing the para­me­ters that the tem­plate accepts after the “@” sign.

Passing Java-backed objects to the JavaScript Use-API

Most of the time, pass­ing Java-backed objects to the JS files is not nec­es­sary, because the same objects avail­able in HTL are also avail­able in the Use-API log­ic. But there’s one case where this is need­ed, when a piece of HTML has been iso­lat­ed in a reusable tem­plate, like in the pre­vi­ous exam­ple. If the tem­plate receives some para­me­ters and needs to exe­cute some log­ic on them, then the received para­me­ters must be passed as well to the JS log­ic.

My HTL com­po­nent still remains the same as pre­vi­ous exam­ple:

<h2>Child Pages</h2>
<div data-sly-use.template="templates.html"
     data-sly-call="${template.pageChildren @ parent=currentPage}"></div>

But my tem­plate now uses the asso­ci­at­ed “pageChildren.js” JS file, and maks its result avail­able in a “log­ic” vari­able, which is then used to iter­ate with data-sly-list:

<sly data-sly-template.pageChildren="${@ parent}"
     data-sly-use.logic="${'pageChildren.js' @ parent=parent}">
    <ul data-sly-list="${logic.children}">
        <li>${item.title}</li>
    </ul>
</sly>

And this is the asso­ci­at­ed JS file, which will remove all invalid and hid­den pages from the list:

var PageFilter = Packages.com.day.cq.wcm.api.PageFilter;

use(function () {
    var filter = new PageFilter(request);
    var children = this.parent.listChildren(filter);

    return {
        children: children
    };
});

You can see how I access the passed “par­ent” vari­able via “this.parent”.
Also notice how Java class­es can be accessed over the “Pack­ages” vari­able.

I hope you found these exam­ples use­ful and that they allow you to start using the HTML Tem­plate Lan­guage JavaScript Use-API.

@heervisscher

Read-on

Oth­er posts on the top­ic:

And here oth­er resources to learn more about it:

0 comments