Coder Social home page Coder Social logo

aem-htl-style-guide's Introduction

AEM HTL Style Guide

A style guide for the HTML Template Language (HTL), formerly known as Sightly, the HTML templating system from Adobe Experience Manager (AEM).

Table of Contents

  1. HTML
  2. Comments
  3. Expression language
  4. Block statements

1. HTML

  • 1.1 Avoid inline JavaScript or CSS.

    In order to encourage keeping a clean separation of concerns, HTL has by design some limitations for inline JavaScript or CSS. First, because HTL doesn't parse JavaScript or CSS, and therefore cannot automatically define the corresponding escaping, all expressions written there must provide an explicit context option. Then, because the HTML grammar ignores elements located inside a <script> or <style> elements, no block statement can be used within them.

    Therefore JavaScript and CSS code should instead be placed into corresponding .js and .css files. Data attributes are the easiest way to communicate values to JavaScript, and class names are the best way to trigger specific styles.

    <!--/* Bad */-->
    <section data-sly-use.teaser="com.example.TeaserComponent" class="teaser">
        <h2 class="teaser__title">${teaser.title}</h2>
        <script>
            var teaserConfig = {
                skin: "${teaser.skin @ context='scriptString'}",
                animationSpeed: ${teaser.animationSpeed @ context='number'}
            };
        </script>
        <style>
            .teaser__title {
                font-size: ${teaser.titleFontSize @ context='styleToken'}
            }
        </style>
    </section>
    
    <!--/* Good */-->
    <section data-sly-use.teaser="com.example.TeaserComponent" data-teaser-config="${teaser.jsonConfig}" class="teaser">
        <h2 class="teaser__title teaser__title--font-${teaser.titleFontClass}">${teaser.title}</h2>
    </section>

⬆ back to top

2. Comments

  • 2.1 Use HTL comments.

    Normal HTML comments get rendered to the final markup. To keep the DOM clean, always use HTL comments over normal HTML comments.

    <!-- Never use HTML comments -->
    
    <!--/* Always use HTL comments */-->

⬆ back to top

3. Expression language

  • 3.1 Set a display context only if necessary

    In most cases you can leave out the display context, because it is determined automatically.

    <!--/* Bad */-->
    <a href="${teaser.link @ context = 'uri'}"></a>
    
    <!--/* Good */-->
    <a href="${teaser.link}"></a>
  • 3.2 Use the safest possible display context.

    From the following list of contexts, always choose the one closest to the top that fits your needs:
    number: For whole numbers (in HTML, JS or CSS)
    uri: For links and paths (in HTML, JS or CSS, applied by default for src and href attributes)
    elementName: For HTML element names (applied by default by data-sly-element)
    attributeName: For HTML attribute names (applied by default by data-sly-attribute for attribute names)
    scriptToken: For JavaScript identifiers and keywords
    styleToken: For CSS identifiers and keywords
    scriptString: For text within JavaScript strings
    styleString: For text within CSS strings
    attribute: For HTML attribute values (applied by default for attribute values)
    text: For HTML text content (applied by default for any content)
    html: For HTML markup (it filters out all elements and attributes that could be dangerous)
    unsafe: Unescaped and unfiltered direct output

    <!--/* Bad */-->
    <section data-sly-use.teaser="com.example.TeaserComponent" class="teaser">
        <h4 onclick="${teaser.clickHandler @ context='unsafe'}">${teaser.title}</h4>
        <div style="color: ${teaser.color @ context='unsafe'};">
            ${teaser.htmlContent @ context='unsafe'}
        </div>
    </section>
    
    <!--/* Good */-->
    <section data-sly-use.teaser="com.example.TeaserComponent" class="teaser">
        <h4 onclick="${teaser.clickHandler @ context='scriptToken'}">${teaser.title}</h4>
        <div style="color: ${teaser.color @ context='styleToken'};">
            ${teaser.htmlContent @ context='html'}
        </div>
    </section>
  • 3.3 Avoid writing unnecessary expressions for literals.

    It might sound obvious, but an expression with just a string literal inside equals just that string literal.

    <!--/* Bad */-->
    <sly data-sly-use.clientlib="${'/libs/granite/sightly/templates/clientlib.html'}">
        ...
    </sly>
    
    <!--/* Good */-->
    <sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html">
        ...
    </sly>
  • 3.4 Avoid using the ternary operator unnecessarily.

    Take advantage of the logical || operator to simplify your code.

    <!--/* Bad */-->
    <div class="${cssClass ? cssClass : 'my-class'}"></div>
    
    <!--/* Good */-->
    <div class="${cssClass || 'my-class'}"></div>
  • 3.5 Use the native URI manipulation capabilities of HTL.

    Rolling out a custom URI builder is error prone and hardcoding URL's is even worse. Use HTL URI Manipulation instead, in particular, the extension option.

    <!--/* Bad */-->
    <a href="${component.link}.html"></a>
    
    <!--/* Good */-->
    <a href="${component.link @ extension = 'html'}"></a>
  • 3.6 Drop Method Prefixes When Accessing Properties from Java Getter Functions.

    When following the JavaBeans naming conventions (as you should) to name your getter methods, you can access the properties with their property name directly. You should access properties this way for consistency and readability.

    <!--/* Bad */-->
    <p>${component.getTitle}</p>
    <a href="${item.link}" data-sly-unwrap="${item.isActive}">...</a>
    
    <!--/* Good */-->
    <p>${component.title}</p>
    <a href="${item.link}" data-sly-unwrap="${item.active}">...</a>

⬆ back to top

4. Block statements

  • 4.1 Use the sly tag name for all elements that are not part of the markup.

    HTML elements with the tag name sly are automatically getting unwrapped and will not be part of the final markup.

    <!--/* Bad */-->
    <div data-sly-include="content.html" data-sly-unwrap></div>
    
    <!--/* Good */-->
    <sly data-sly-include="content.html"></sly>
    <!--/* Bad */-->
    <div data-sly-resource="${item @ selectors='event'}" data-sly-unwrap></div>
    
    <!--/* Good */-->
    <sly data-sly-resource="${item @ selectors = 'event'}"></sly>
    <!--/* Bad */-->
    <div data-sly-test="${event.hasDate}" data-sly-unwrap>
        ...
    </div>
    
    <!--/* Good */-->
    <sly data-sly-test="${event.hasDate}">
        ...
    </sly>

    IMPORTANT - The sly element will not automatically unwrap itself if you use HTL 1.0 (AEM 6.0). In that case, you still have to add the data-sly-unwrap attribute.

    <!--/* Bad - HTL 1.0 */-->
    <sly data-sly-include="content.html"></sly>
     
    <!--/* Good - HTL 1.0 */-->
    <sly data-sly-include="content.html" data-sly-unwrap></sly>
  • 4.2 Try to place data-sly-use statements only on top-level elements.

    Since data-sly-use identifiers are always global (https://docs.adobe.com/docs/en/htl/docs/use-api/java.html#Local%20identifier), these attributes should only be placed in the top-level element. That way one can easily see name clashes and also it prevents initializing the same object twice.

    <!--/* Bad */-->
    <section class="teaser">
       <h3 data-sly-use.teaser="com.example.TeaserComponent">${teaser.title}</h3>
    </section>
    
    <!--/* Good */-->
    <section data-sly-use.teaser="com.example.TeaserComponent" class="teaser">
       <h3>${teaser.title}</h3>
    </section>
  • 4.3 Use meaningful identifier names.

    This will enhance the readability of your HTL scripts and and makes it easier for others to understand.

    <!--/* Bad */-->
    <sly data-sly-use.comp="com.example.TeaserComponent">
        ...
    </sly>
     
    <!--/* Good */-->
    <sly data-sly-use.teaser="com.example.TeaserComponent">
        ...
    </sly>
  • 4.4 Use lowerCamelCase for identifier names.

    Using lowerCamelCase (You start by making the first word lowercase. Then, you capitalize the first letter of each word that follows i.e.: "sampleIdentifierName") will help to increase the readability of your identifiers. Notice though that HTL will internally only use (and log) full lowercase identifiers. Also dashes are not allowed for identifiers.

    <!--/* Bad */-->
    <sly data-sly-use.mediagallery="com.example.MediaGallery">
        ...
    </sly>
    
    <!--/* Good */-->
    <sly data-sly-use.mediaGallery="com.example.MediaGallery">
        ...
    </sly>
  • 4.5 Re-use expressions with identifiers

    If a test block statement is used multiple times, define an identifer and re-use it this way instead. This will allow the htl compiler to cache the expression result and will also make your code easier to read and understand.

    <!--/* Bad */-->
    <section data-sly-test="${!teaser.empty}" class="teaser">
        ...
    </section>
     
    <div data-sly-test="${teaser.empty}" class="cq-placeholder"></div>
     
    <!--/* Good */-->
    <section data-sly-test.hasContent="${!teaser.empty}" class="teaser">
        ...
    </section>
     
    <div data-sly-test="${!hasContent}" class="cq-placeholder"></div>

    Similarly, if a generic expression is used multiple times, define an identifer with data-sly-set and re-use it, for the same reasons stated above.

    <!--/* Bad */-->
    <div data-sly-unwrap="${!(wcmmode.edit || wcmmode.preview) || resource.hasChildren}">
        <sly
            data-sly-test="${resource.hasChildren}"
            ...>
        </sly>
        <sly
            data-sly-test="${(wcmmode.edit || wcmmode.preview) && !resource.hasChildren}"
            .... >
        </sly>
    </div>
     
    <!--/* Good */-->
    <div
         data-sly-set.editMode="${(wcmmode.edit || wcmmode.preview)}"
         data-sly-set.hasChildren="${resource.hasChildren}"
         data-sly-unwrap="${!editMode || hasChildren}">
        <sly
            data-sly-test="${hasChildren}"
            ...>
        </sly>
        <sly
            data-sly-test="${editMode && !hasChildren}"
            ...>
        </sly>
    </div>
  • 4.6 Use identifiers instead of the default “item” variable for list block statements.

    <!--/* Bad */-->
    <ul data-sly-list="${tagList.tags}" class="tagList">
        <li class="tagList__tag">
            <a class="tagList__button" href="${item.url}">${item.title}</a>
        </li>
    </ul>
     
    <!--/* Good */-->
    <ul data-sly-list.tag="${tagList.tags}" class="tagList">
        <li class="tagList__tag">
            <a class="tagList__button" href="${tag.url}">${tag.title}</a>
        </li>
    </ul>
  • 4.7 Place block statements before the regular HTML attributes.

    The reason for that is that regular HTML attributes might use HTL variables which have been declared in the same element via data-sly-use. One should always declare things before using them. Also HTL block elements might influence if the element appears at all (via data-sly-test) or multiple times (via data-sly-repeat) and therefore are just too important to put them at the end of the attribute list. Further details in issue 25.

    <!--/* Bad */-->
    <p class="teaser__text" data-sly-test="${teaser.text}"></p>
         
    <!--/* Good */-->
    <p data-sly-test="${teaser.text}" class="teaser__text"></p>
  • 4.8 Use existing HTML elements for your block statements if possible.

    <!--/* Bad */-->
    <sly data-sly-test="${!teaser.active}">
        <section class="teaser"></section>
    </sly>
     
    <!--/* Good */-->
    <section data-sly-test="${!teaser.active}" class="teaser"></section>
  • 4.9 Avoid the element, attribute and text block statements.

    It's a lot cleaner and explicit to write your HTL scripts without these block statements.

    <!--/* Bad */-->
    <div data-sly-element="${headlineElement}">${event.year}</div>
    <a data-sly-attribute.href="${event.link}" href="#"></a>
    <p data-sly-text="${event.year}" class="event__year"></p>
     
    <!--/* Good */-->
    <h2>${event.year}</h2>
    <a href="${event.link}"></a>
    <p class="event__year">${event.year}</p>
  • 4.10 Define your templates in a separate file.

    It's cleaner to create separate files for your template markup, so your HTL scripts will not get cluttered.

    <!--/* Bad */-->
    <sly data-sly-use.teaser="com.example.TeaserComponent">
      <sly data-sly-template.teaserSmall="${@ title, text}">
        <h2>${title}</h2>
        <p>${text}</p>
      </sly>
      
      <sly data-sly-call="${teaserSmall @ title=teaser.title, text=teaser.text}"></sly>
    </sly>
    
    <!--/* Good - Separate template file: "teaser-templates.html" */-->
    <sly data-sly-template.teaserSmall="${@ teaserModel}">
      <h2>${teaserModel.title}</h2>
      <p>${teaserModel.text}</p>
    </sly>
    
    <!--/* Good - HTL script */-->
    <sly data-sly-use.teaser="com.example.TeaserComponent" data-sly-use.teaserTemplates="teaser-templates.html">
      <sly data-sly-call="${teaserTemplates.teaserSmall @ teaserModel=teaser}"></sly>
    </sly>
  • 4.11 Avoid using data-sly-test to set arbitrary variable bindings

    Instead of binding a variable with data-sly-test, use the purposefully defined data-sly-set. This avoids unintentionally hiding elements if the result of the expression evaluates to false (see HTL expressions evaluating to false ) and/or stopping the evaluation of further block statements; This is specially difficult to debug when various data-sly-test statements affect the same element.

    <!--/* Instead of */-->
    <sly data-sly-test="${person.firstName && person.lastName && person.image}" data-sly-test.fullName="${person.firstName} ${person.lastName}">
    <h1>${fullName}</h1>
    <img src=${person.image}" alt="${fullName}"/>
    
    <!--/* Use */-->
    <sly data-sly-test="${person.firstName && person.lastName && person.image}" data-sly-set.fullName="${person.firstName} ${person.lastName}">
    <h1>${fullName}</h1>
    <img src=${person.image}" alt="${fullName}"/>
  • 4.12 Avoid unnecessary <sly> tags.

    It's cleaner and easier to understand your intentions if you add your block statements in the relevant elements directly instead of wrapping them with an sly tag.

    <!--/* Bad */-->
    <sly data-sly-test.title="${component.title}">
      <h1>${title}</h1>
    </sly>
    
    <!--/* Good */-->
    <h1 data-sly-test.title="${component.title}">${title}</h1>
  • 4.13 Use an explicit </sly> end tag to close <sly> tags.

    Because sly is neither a void nor a foreign element (See html5 start tags), it must be explicitly closed with an end tag </sly>. Using a self-closing tag is not allowed.

    <!--/* Bad */-->
    <sly data-sly-include="content.html"/>
    
    <!--/* Good */-->
    <sly data-sly-include="content.html"></sly>

⬆ back to top

License

The MIT License (MIT)

Copyright (c) 2015 Netcentric

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

⬆ back to top

aem-htl-style-guide's People

Contributors

apenpfkkhm avatar felipes avatar gabrielwalt avatar karollewandowski avatar kwin avatar paulochang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aem-htl-style-guide's Issues

Clarify "4.2 Try to place use data-sly-use statements only on root elements."

I'm not sure if I correctly understand rule 4.2. What does "root element" mean? Is it just top level element:

<div> <!-- this is root element -->
    <span>test</span>
</div>
<section> <!-- this is root element -->
    lorem ipsum
</section>

or first top level element in file?

<div> <!-- this is root element -->
    <span>test</span>
</div>
<section> <!-- this is NOT root element -->
    lorem ipsum
</section>

The identifiers in Sightly should always be lowercase only

As the identifiers in Sightly (at least the one for the template identifier) are internally converted to lowercase, they should only be defined in lowercase in the first place. Otherwise one might run into collisions when defining a template named "myTemplate" and "mytemplate" in the same script, because to Sightly those identifiers are the same.
Reason is primarily that Sightly logs everything with the internal (lowercased) identifiers and finding the appropriate location in the Sightly script is much easier, if the identifier is also used in lower case in the script.

Suggested improvements

I suggest the following improvements to make it easier to reorganise code (moving sightly instructions around, etc.) and also to improve readability. These suggestions come from my firsthand experience on working with Sightly on a large AEM project. There you often need to reorganise code and change control flow, which is way easier, when these things are separate tags instead of sticking everything on one HTML tag. Also, readability gets really bad with the currently suggested rules. As an example, we have components on our project with several use classes on the root element, plus we also have a test statement on the root element and finally we also have some special CSS classes on this root element which are generated by the use classes.

4.2 - Do not put the use tags on the regular root element. Instead, i would put them in a separate sly tag at the top of the file. Also, i would put a separate sly tag for each use js/java class. In that way it is easier to change the application structure without having to move attributes around, creating tags, etc.:

<sly data-sly-use.teaser="com.example.FirstComponent" />
<sly data-sly-use.somethingElse="com.example.SecondComponent" />
<section class="teaser">
    <h3>${teaser.title}</h3>
</section>

4.7 and 4.8 - I suggest to actually put control statements on separate sly tags to disentangle the control logic from the actually output HTML. In that way it is easier to change the control / flow of the execution without having to move attributes around:

<sly data-sly-test="${teaser.text}">
<p class="teaser__text"></p>
</sly>

Use data-sly-resource with option resourceType when possible

If the resourceType option is left out and the referenced resource does not exist (i.e. for pages being created based on an old template that didn't have that resource) Sightly will throw a org.apache.sling.api.resource.ResourceNotFoundException for the data-sly-resource statement. To prevent that the resourceType should be given wherever possible. That way the Sightly script will still render fine and the resource will be automatically created the first time the edit dialog is submitted by the author. That way pages do not have to be manually migrated/recreated once a new component is added.

The only cases where this is not possible are

  • directly within a parsys (where arbitrary resourceTypes are supported). There is never a problem with these includes, as only existing child resources should lead to rendering a component (non-existing resources are never used with such a data-sly-resource)
  • in reference components referencing other content as is (i.e. without possibility to edit). In that case the path is given by the editor and throwing an exception in case an inexisting path is used there is fine for that as well.

Use heading sintax

@raohmaru Pointed to me that Github already adds links when using the Heading syntax.
To keep the markdown simple, it would probably be good to change our docs to use this functionality directly instead of creating the links manually as we do right now.

It should be noted however, that this might make our docs less portable if we want to migrate out.

Reason for: 4.7 Always place block statements after the normal HTML attributes

Hi guys,
I'm working on AEM IntelliJ Plugin which supports HTL and got issue report about variables resolving.
In such code:
unresolved references
variables are unresolved because in the plugin I assume that (according to HTL specification) identifiers scope for data-sly-use, data-sly-test, data-sly-set and data-sly-unwrap is specified as:

Scope: The identifier set by the * block element is global to the script and can be used anywhere after its declaration.

For me, the "after its declaration" phrase means that usage before the declaration is disallowed. Maybe I'm wrong with interpretation.

My question is: what is the reason for adding rule 4.7 to the style guide? In my opinion, code is hard to read when declarations are specified after actual usages and I would even add rule exactly opposite to the current 4.7 - to put HTL blocks always before any other attributes. Is there any technical reason for the current state or it was introduced for better code organization and putting standard attributes before HTL blocks was a random decision or a matter of taste? Maybe it's worth to change it to make code cleaner and follow HTL spec?

Add a rule for using data-sly-use only in the root element

Since the scope of everything being included via data-sly-use is always global to the current Sightly file (http://docs.adobe.com/docs/en/aem/6-0/develop/sightly/block-statements.html#use) it would be good to use data-sly-use only at the root element. That way one can see at first glance which things are imported. Otherwise the same e.g. template might be imported multiple times, which leads to

  • a warning from the org.apache.sling.scripting.sightly.impl.compiler.util.GlobalShadowChecker
  • performance degradation as things are initialized multiple times

Example of §4.2 doesn't comply with §4.8

The following example doesn't comply with §4.8 (Always use existing HTML elements for your block statements if possible).

<sly data-sly-use.teaser="com.example.TeaserComponent">
    <div class="teaser">
        <a class="teaser__link" href="${teaser.link}"></a>
    </div>
</sly>

Because as far as I understand the style guide, §4.8 would request it to be written as follows:

<div class="teaser" data-sly-use.teaser="com.example.TeaserComponent">
    <a class="teaser__link" href="${teaser.link}"></a>
</div>

Maybe a better example would be something like the following:

<!--/* Bad */-->
<p data-sly-use.foo="Foo">${foo.one}</p>
<p>${foo.two}</p>

<!--/* Good */-->
<sly data-sly-use.foo="Foo">
    <p>${foo.one}</p>
    <p>${foo.two}</p>
</sly>

Add some rule about empty lines

Currently the Sightly Compiler will never remove any blank lines from the HTML (see https://issues.apache.org/jira/browse/SLING-4443).
That may lead to problems because a code like this

<sly data-sly-use="..." data-sly-unwrap />
<!DOCTYPE>

will lead to an output like this


<!DOCTYPE>

There is an empty first line being rendered by the Sightly script.
One solution would be to always have the end tag of data-sly-unwrap elements at the beginning of the new line, so you would rather write it like this

<sly data-sly-use="..." data-sly-unwrap 
/><!DOCTYPE>

Use suffix/prefix for the identifiers to distinguish between the different types (and prevent name clashes)

It is often hard to distinguish between the different types of identifiers used within a Sightly file.
The following types of identifiers should be distinguishable by only looking the identifier itself:

  • JavaScript/Java object mapped via data-sly-use
  • Template library initialized via data-sly-use
  • Template name defined via data-sly-template

I propose to use different prefixes/suffixes for those types.
Those prefixes/suffixes will also prevent any name clashing will other predefined global objects: http://docs.adobe.com/docs/en/aem/6-0/develop/sightly/global-objects.html

Merge / Update style guide to follow Adobe's

It seems that Adobe copied a lot of our style guide for their own wiki

https://github.com/adobe/aem-core-wcm-components/wiki/htl-style-guide

Our style guide is a bit more strict in some ways...

i.e.:

Always use HTL comments.

Normal HTML comments get rendered to the final markup. To keep the DOM clean, always use HTL comments over normal HTML comments.

vs

Prefer HTL Comments Over HTML Comments
HTML comments are rendered in the final markup, so unless there is a specific need, HTL comments are always preferred.

this, I find okay.

But we could probably adopt some of their recommendations:
i.e.:

Drop Method Prefixes When Accessing Properties from Java Getter Functions

I think it'd be good to do a revision of our recommendations.

I will open a few PR's and will await your comments.

Update HTL Guide with latest developments

HTL Spec was updated in June 2018 to support variable setting via data-sly-set (https://github.com/adobe/htl-spec/blob/1.4/SPECIFICATION.md#2212-set) and available in AEM 6.5 (https://docs.adobe.com/content/help/en/experience-manager-65/release-notes/sites.html), AEM 6.3 SP3 and AEM 6.4 SP1 (https://github.com/adobe/htl-spec).

This potentially means we should now recommend the usage of data-sly-set when possible.

We should probably also mention that setting up variables by abusing the data-sly-test.identifier pattern for cases other than test blocks is to be avoided when possible.(https://github.com/Netcentric/aem-htl-style-guide#4.5).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.