htl(sightly) - all you need to know

41
www.tothenew.com HTML Template Language

Upload: prabhdeep-singh

Post on 20-Mar-2017

55 views

Category:

Software


9 download

TRANSCRIPT

Page 1: HTL(Sightly) - All you need to know

www.tothenew.com

HTML Template Language

Page 2: HTL(Sightly) - All you need to know

www.tothenew.com

Agenda

● What is HTL?● Why HTL?● Global Objects● HTL Block Statements● HTL Use-API● HTL Expression Options● Best Practises

Page 3: HTL(Sightly) - All you need to know

www.tothenew.com

What is HTML Template Language (HTL)?

● Introduced with AEM 6.0● Takes the place of JSP as the preferred server-side template system

for HTML● Enforces separation of concerns between Presentation & Business

logic● A HTL file contains HTML, some basic presentation logic and

variables to be evaluated at runtime● Sightly was renamed to “HTML Template Language” from August

2016

Page 4: HTL(Sightly) - All you need to know

www.tothenew.com

Why HTL?

● Simplified Development: ○ Purposely limited features: Easy to learn and enforces strict

separation of concerns between markup and logic.○ HTL template is itself a valid HTML5 file: Doesn't break the validity of

the markup and keeps it readable○ Allows HTML developers without Java knowledge and with little

product-specific knowledge to be able to edit HTL templates○ Allows Java developers to focus on the back-end code without

worrying about HTML

After Sightly

Page 5: HTL(Sightly) - All you need to know

www.tothenew.com

Why HTL?

● Increased Security:

○ HTL automatically filters and escapes all text being output to the presentation layer to prevent cross-site-scripting(XSS) vulnerabilities.

○ Automatically applies the proper context-aware escaping to all variables being output to the presentation layer

Page 6: HTL(Sightly) - All you need to know

www.tothenew.com

AEM HTL Read–Eval–Print Loop

● To try out basic HTL, a live execution environment called the Read Eval Print Loop can be used.

● Download Link & documentation:https://github.com/Adobe-Marketing-Cloud/aem-htl-repl

● After package installation, go to /content/repl.html

?

Page 7: HTL(Sightly) - All you need to know

www.tothenew.com

HTL Syntax

• Every HTL file is an HTML5 document or fragment, augmented with a specific syntax that adds the dynamic functionality.

There are two different kind of Syntaxes:-

• HTL Block Statements:- To define structural block elements within HTL file, HTL employs HTML5 data attributes. This allows to attach behavior to existing HTML elements. Block statements can't be used inside html comments, style n script elements. A block statement starts with data-sly.

• HTL Expressions:- HTL expressions are delimited by characters ${ and }. At runtime, these expressions are evaluated and their value is injected into the outgoing HTML stream. Expressions can only be used in attribute values, in element content, or in comments.

Page 8: HTL(Sightly) - All you need to know

www.tothenew.com

Example

<h1 data-sly-test="${currentPage.title}">    <a href="${currentPage.path}.html">        ${currentPage.title}    </a></h1>

• Output

<h1>    <a href="/content/my%20page.html">        My page title&#x21;    </a></h1>

Page 9: HTL(Sightly) - All you need to know

www.tothenew.com

Useful Objects Available

• properties• pageProperties• Component• currentDesign• currentPage• log• out• pageManager• request• resource• response• sling• wcmmode

Page 10: HTL(Sightly) - All you need to know

www.tothenew.com

Comments

HTL comments are HTML comments with additional syntax. They are delimited like this:

<!--/* A HTL Comment */-->

However, the content of standard HTML comments, delimited like this:<!-- An HTML Comment -->

will be passed through the HTL processor and expressions within the comment will be evaluated.

Page 11: HTL(Sightly) - All you need to know

www.tothenew.com

HTL Block Statements

● dat-sly-test

● data-sly-resource

● data-sly-include

● data-sly-attribute

● data-sly-element & data-sly-text

● data-sly-list

● data-sly-template & dat-sly-call

● data-sly-use

● data-sly-unwrap

Page 12: HTL(Sightly) - All you need to know

www.tothenew.com

data-sly-test

• Conditionally removes the host element and it‘s content if an expression evaluates to false.

• Values that can be converted to false are: undefined variables, null values, the number zero, and empty strings.

• data-sly-test also sup ports the naming and reuse of tests.

Example

<div data-sly-test.author="${wcmmode.edit || wcmmode.design}"> Show this to the author

</div> <div data-sly-test="${!author}">

Not in author mode anymore.. </div>

Page 13: HTL(Sightly) - All you need to know

www.tothenew.com

• data-sly-include : Includes the output of a rendering script run with the current context, passing back control to the current Sightly script.

<div data-sly-include="template.html"></div><div data-sly-include="template.jsp"></div>

• The element on which a data-sly-include has been set is ignored and not displayed

data-sly-include

Page 14: HTL(Sightly) - All you need to know

www.tothenew.com

data-sly-resource

• Includes a rendered resource from the same server, using an absolute or relative path.Examples:<div data-sly-resource="${ @path='par', resourceType='foundation/components/parsys'}"/>With an expression more options can be specified:<section data-sly-resource="${'my/path' @ appendPath='appended/path'}"></section><section data-sly-resource="${'my/path' @ prependPath='prepended/path'}"></section>

Manipulating selectors:<section data-sly-resource="${'my/path' @ selectors='selector1.selector2'}" /><section data-sly-resource="${'my/path' @ addSelectors=['selector1', 'selector2']}" /><section data-sly-resource="${'my/path' @removeSelectors=['selector1','selector2']}" />

By default, the AEM decoration tags are disabled, the decorationTagName option allows to bring them back, and the cssClassName to add classes to that element.

<article data-sly-resource="${'path/to/resource' @ decorationTagName='span',cssClassName='className'}"></article>

Page 15: HTL(Sightly) - All you need to know

www.tothenew.com

data-sly-attribute

• Sets an attribute or a group of attributes on the current element :<tag class="className" data-sly-attribute.class="${myVar}"></tag> This overwrites the content of the class attribute

Assuming that foobar = {'id' : 'foo', 'class' : 'bar'} ,<input data-sly-attribute="${foobar}" type="text"/>outputs : <input id="foo" class="bar" type="text"/>

• Attributes are processed left-to-right :<div class="bar1" data-sly-attribute.class="bar2" data-sly-attribute="${foobar}"></div>outputs: <div id="foo" class="bar"></div>

Page 16: HTL(Sightly) - All you need to know

www.tothenew.com

• Changes the element, mostly useful for setting element tags like h1..h6, th, td, ol, ul :

<div data-sly-element"${'h1'}">Sightly Element Example</div>outputs: <h1>Sightly Element Example</h1>

For security reasons, data-sly-element accepts only the following element names: a abbr address article aside b bdi bdo blockquote br caption cite code col colgroup data dd del dfn div dl dt em figcaption figure footer h1 h2 h3 h4 h5 h6 header i ins kbd li main mark nav ol p pre q rp rt ruby s samp section small span strong sub sup table tbody td tfoot th thead time tr u var wbr

data-sly-text

• Replaces the content of its host element with the specified text.

<p data-sly-text="${properties.jcr:description}">Lorem ipsum</p>

data-sly-element

Page 17: HTL(Sightly) - All you need to know

www.tothenew.com

data-sly-list● Repeats the content of the host element for each property in the provided

object.<ul data-sly-list="${currentPage.listChildren}"> <li> index: ${itemList.index}, value: ${item.title} </li> </ul><ul data-sly-list.child="${myObj}">

<li> key: ${child}, value: ${myObj[child]} </li></ul>

● itemList holds the following properties:index: zero-based counter (0..length-1).count: one-based counter (1..length).first: true if the current item is the first item.middle: true if the current item is neither the first nor the last item.last: true if the current item is the last item.odd: true if index is odd.even: true if index is even.

Page 18: HTL(Sightly) - All you need to know

www.tothenew.com

● Template blocks can be used like function calls:

○ Parameters can be passed when calling templates.

○ They also allow recursion.

● Template Declaration :

<template data-sly-template.example="${@ class, text}">

<span class="${class}">${text}</span>

</template>

● Call Statement :

<div data-sly-call="${example @ class=‘css-class', text='Hi'}"></div>

● Output:

<div><span class="css-class">Hi</span></div>

Template & Call Statements

Page 19: HTL(Sightly) - All you need to know

www.tothenew.com

• Initializes a helper object (defined in JavaScript or Java) and exposes it through a variable:

JS: <div data-sly-use.page="customPage.js">${page.foo}</div>Java: <div data-sly-use.nav="Navigation">${nav.foo}</div>

• Parameters can be passed to the Use-API by using expression options:<div data-sly-use.nav="${'Navigation' @ depth=1,showVisible=!wcmmode.edit}">

${nav.foo}</div>

• Also used to load data-sly-template markup snippets located in a different file :

data-sly-use

<!-- library.html --><template data-sly-template.foo="${@ text}"> <span class="example">${text}</span></template>

<!-- template.html --><div data-sly-use.library="library.html" data-sly-call="${library.foo @ text='Hi'}"> </div>

Output:<div><span class="example">Hi</span></div>

Page 20: HTL(Sightly) - All you need to know

www.tothenew.com

HTL Use-API

Java Use-API JavaScript Use-API

Pros ● faster● can be inspected with a

debugger● easy to unit-test

● can be modified by front-end developers

● is located within the component, keeping the view logic of a component close to its corresponding template

Page 21: HTL(Sightly) - All you need to know

www.tothenew.com

Java Use-API enables a HTL file to access helper methods in a custom Java class.

1. Implementing Use interface:

public class HTLComponent implements Use { @Override public void init(Bindings bindings) { Resource resource = (Resource)bindings.get("resource"); ValueMap properties = (ValueMap)bindings.get("properties");

// Parameters passed to the use-class String param1 = (String) bindings.get("param1");

}

In AEM 6.2, io.sightly.java.api.Use is deprecated, org.apache.sling.scripting.sightly.pojo.Use is used instead.

Java Use-API

Page 22: HTL(Sightly) - All you need to know

www.tothenew.com

Java Use-API

2. Extend WCMUsePojo class:

public class HTLComponent extends WCMUsePojo { private String myTitle; @Override

public void activate() { String text = get("text", String.class);myTitle = "My Project " + text + getCurrentPage().getTitle()

+ “ : ” + getProperties().get("title", ""); }public String getMyTitle() { return myTitle; }

}

In AEM 6.2, WCMUse is deprecated, com.adobe.cq.sightly.WCMUsePojo used instead.

Page 23: HTL(Sightly) - All you need to know

www.tothenew.com

• If the Java source file is in the same folder as the HTL file<div data-sly-use.nav="Navigation">${nav.foo}</div>

Otherwise,<div data-sly-use.nav="com.htl.model.Navigation">${nav.foo}</div>

• HTL Use-API resolutionFind a Java UseClass in the same directory OR with a fully qualified class nameTry to adapt the current Resource/Request to UseClass, if unsuccessful, try to

instantiate UseClass with a zero-argument constructor.Within HTL, bind the newly adapted or created object to the localName.If UseClass implements the Use interface then call the init method, passing the

current execution context (a javax.scripting.Bindings object).UseClass extending WCMUse is a special case of implementing Use providing the

convenience context methods and its activate method is automatically called from Use.init.

If UseClass is a path to a HTL file containing a data-sly-template, prepare the template.

Otherwise, if UseClass is a path to a JavaScript use-class, prepare the use-class.

data-sly-use (cont.)

Page 24: HTL(Sightly) - All you need to know

www.tothenew.com

• Enables a HTL file to access helper code written in JavaScript.• Allows all complex business logic to be encapsulated in the JavaScript code, while the HTL

code deals only with direct markup production.

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 };});

data-sly-use JavaScript Use Api

Page 25: HTL(Sightly) - All you need to know

www.tothenew.com

Client libraries helper template library

The client libraries helper template library (/libs/granite/HTL/templates/clientlib.html) can be loaded through data-sly-use and stored in a clientLib block element variable. Loading the library's CSS style sheets and JavaScript is done through data-sly-call. The clientLib template library exposes three templates:

• css - loads only the CSS files of the referenced client libraries• js - loads only the JavaScript files of the referenced client libraries• all - loads all the files of the referenced client libraries

Page 26: HTL(Sightly) - All you need to know

www.tothenew.com

Client libraries helper template library Example

<head data-sly-use.clientLib="${'/libs/granite/HTL/templates/clientlib.html'}">

<css data-sly-call="${clientLib.css @ categories=['category1', 'category2']}" data-sly-unwrap/>

</head><body> <!-- content --> <js data-sly-call="${clientLib.js @ categories=['category1',

'category2']}" data-sly-unwrap/></body>

Page 27: HTL(Sightly) - All you need to know

www.tothenew.com

• The <sly> HTML tag can be used to remove the current element, allowing only its children to be displayed:

<sly data-sly-test="${event.hasDate}" > <span>Hello</span>

</sly>• Its functionality is similar to the data-sly-unwrap block element :

<div data-sly-test="${event.hasDate}" data-sly-unwrap> <span>Hello</span>

</div>

Both Output : <span>Hello</span>

• Although not a valid HTML 5 tag, the <sly> tag can be displayed in the final output using data-sly-unwrap:

<sly data-sly-unwrap="${false}"></sly>outputs: <sly></sly>

<sly> & data-sly-unwrap

Page 28: HTL(Sightly) - All you need to know

www.tothenew.com

Expression Options

Page 29: HTL(Sightly) - All you need to know

www.tothenew.com

Display Context Option

The context option offers control over escaping and XSS protection.

• Allowing some HTML markup (filtering out scripts)<div>${‘<p>Hello</p>’ @ context='html'}</div>

Without context : &lt;p&gt;hello&lt;/p&gt;

• Adding URI validation protection <p data-link="${link @ context='uri'}">text</p>

• Applying CSS string escaping <style> a { font-family: "${myFont @ context='styleString'}"; } </style>

Page 30: HTL(Sightly) - All you need to know

www.tothenew.com

Display Context Option

Context Use• html• text • elementName• uri • scriptString • scriptComment • scriptRegExp • styleString • styleComment • comment • number • unsafe

Outputs HTML - Removes markup that may contain XSS risks For simple HTML content - Encodes all HTML Allows only element names that are white-listed, else outputs 'div'To get valid Href link or pathApplies JavaScript string escaping For JavaScript block commentsTo apply JavaScript regular expression escaping To apply CSS string escaping For CSS commentsTo apply HTML comment escaping Outputs zero if the value is not a number Disables XSS protection completely, use this at your own risk.

Page 31: HTL(Sightly) - All you need to know

www.tothenew.com

String Format Option

Numbered parameters can be used for injecting variables:

${'Assets {0}' @ format=properties.assetName}OR

${'Assets {0}' @ format=[properties.assetName]}

${'Page {0} of {1}' @ format=[current, total]}

Array Join Option

The join option allows to control the output of an ahorray object by specifying the separator string. This can for e.g. be useful for setting class-names

${['one', 'two'] @ join='; '} <!--/* outputs: one; two */-->

<span class="${myListOfClassNames @ join=' '}"></span>

Page 32: HTL(Sightly) - All you need to know

www.tothenew.com

Internationalization (@i18n)

To translate a string to the resource language:

${'Assets' @ i18n}

Two more options can be used with i18n:• locale : Overrides the language from the source. For e.g.: en-US or fr-CH• hint : Allows to provide some information about the context for the translators.

${'Assets' @ i18n, locale='en-US', hint='Translation Hint'}

Page 33: HTL(Sightly) - All you need to know

www.tothenew.com

URI Manipulation

• Scheme - Allows adding or removing the scheme part for a URI : ${'example.com/path/page.html' @ scheme='http'}outputs: http://example.com/path/page.html

${'http://example.com/path/page.html' @ scheme='https'}outputs: https://example.com/path/page.html

• Domain - Allows adding or replacing the host and port (domain) part for a URI : ${'///path/page.html' @ domain='example.org'}outputs: //example.org/path/page.html

${'http://www.example.com/path/page.html' @ domain='www.example.org'}outputs: http://www.example.org/path/page.html

Page 34: HTL(Sightly) - All you need to know

www.tothenew.com

URI Manipulation

Path / prependPath / appendPath – Modify the path that identifies a resource :

${'http://example.com/this/one.selector.html/suffix?key=value’@ path='that/two'}outputs: http://example.com/that/two.selector.html/suffix?key=value#

${'http://example.com/this/one.selector.html/suffix?key=value' @ path=‘’}outputs: http://example.com/this/one.selector.html/suffix?key=value

${'path' @ prependPath='..'}outputs: ../path

${'http://example.com/path/page.html' @ prependPath='foo'}outputs: http://example.com/foo/path/page.html

${'one' @ appendPath='two'}outputs: one/two

Page 35: HTL(Sightly) - All you need to know

www.tothenew.com

URI Manipulation

Selectors / addSelectors / removeSelectors - Modifies or removes the selectors from a URI:

${'path/page.woo.foo.html' @ selectors='foo.bar'}outputs: path/page.foo.bar.html

${'path/page.woo.foo.html' @ selectors=['foo', 'bar']}outputs: path/page.foo.bar.html

${'path/page.woo.foo.html' @ addSelectors='foo.bar'}outputs: path/page.woo.foo.bar.html

${'path/page.woo.foo.html' @ removeSelectors=['foo', 'bar']}outputs: path/page.woo.html

Page 36: HTL(Sightly) - All you need to know

www.tothenew.com

URI Manipulation

query / addQuery / removeQuery- adds, replaces or removes the query segment of a URI, depending on the contents of its map value :

assuming that jsuse.query evaluates to: { "query": { "q" : "sightly", "array" : [1, 2, 3] } }

${'http://www.example.org/search' @ query=jsuse.query}outputs: http://www.example.org/search?q=sightly&amp;array=1&amp;array=2&amp;array=3

${'http://www.example.org/search?s=1' @ addQuery=jsuse.query}outputs: http://www.example.org/search?s=1&amp;q=sightly&amp;array=1&amp;array=2&amp;array=3

${'http://www.example.org/search?s=1&q=sightly' @ removeQuery=['s', 'q']}outputs: http://www.example.org/search

Page 37: HTL(Sightly) - All you need to know

www.tothenew.com

URI Manipulation

• Extension - adds, modifies or removes the extension from a URI: ${'path/page.json?key=value' @ extension='html'}outputs: path/page.html?key=value

${'path/page.json#fragment' @ extension='html'}outputs: path/page.html#fragment

• fragment - adds, modifies or replaces the fragment segment of a URI :${'path/page' @ fragment='fragment'}

outputs: path/page#fragment

${'path/page#one' @ fragment='two'}outputs: path/page#two

${'path/page#one' @ fragment}outputs: path/page

Page 38: HTL(Sightly) - All you need to know

www.tothenew.com

Best practices

● Abuse of sly

● HTL comments instead of Html comments

● Reuse code using templates

● Use api to be used only when the HTL file alone is not enough to

implement logic

● Javascript use is slower than Java use class so use Javascript only for

less intensive logic

● Use local java use class if the class is used only for that component,

otherwise create a bundle use class

● Passing a parameter to a use-class should only be done when the use-

class is used in a data-sly-template file which itself is called from another

HTL file with parameters that need to be passed on.

Page 39: HTL(Sightly) - All you need to know

www.tothenew.com

Moving from JSP to HTL

• Components written in HTL are compatible with components written in JSP or ESP.

A JSP can include a HTL file like this,• <cq:include script="footer.html"/>and a HTL file can include a JSP like this,<div data-sly-include="footer.jsp"></div>

Page 40: HTL(Sightly) - All you need to know

www.tothenew.com

• HTL Specification :https://docs.adobe.com/docs/en/htl/overview.htmlhttps://github.com/Adobe-Marketing-Cloud/sightly-spec/blob/master/SPECIFICATION.md#31-sly

• Gabriel Walt’s Slideshare PPT:http://www.slideshare.net/GabrielWalt/component-development

• http://www.netcentric.biz/blog/2015/08/aem-sightly-style-guide.html

• http://www.citytechinc.com/content/dam/circuit/Component%20Development.pdf

• http://stackoverflow.com/questions/27583326/expression-option-sightly

References

Page 41: HTL(Sightly) - All you need to know

www.tothenew.com