HTL Tutorial #2: Expressions and Data Types

HTL Tutorial #2: Expressions and Data Types

Expression Syntax

HTL expressions are enclosed between ${ and } and can contain:

  • Identifiers (variables)
  • Literals (fixed values)
  • Operators
  • Property access
${variable}
${'literal string'}
${number}
${object.property}

Identifiers

Identifiers are variable names that reference data:

<!-- Component properties -->
${properties.title}

<!-- Current page properties -->
${currentPage.title}

<!-- Defined variables -->
${myVariable}

Available Global Objects

HTL provides several global objects:

Object Description
properties Current component properties
currentPage Current page
pageProperties Current page properties
inheritedPageProperties Properties inherited from hierarchy
component Component metadata
resource Current Sling resource
request HTTP request
wcmmode WCM mode (edit, preview, disabled)

Practical example:

<article>
  <h1>${currentPage.title}</h1>
  <p class="subtitle">${pageProperties.subtitle}</p>
  <time>${properties.publishDate}</time>
</article>

Literal Data Types

1. Strings

Strings enclosed in single or double quotes:

<!-- Single quotes -->
${'Welcome'}

<!-- Double quotes -->
${"Hello World"}

<!-- With escaping -->
${'It\'s a beautiful day'}
${"He said: \"Hello\""}

Supported escape sequences:

\b  → backspace
\t  → tab
\n  → newline
\f  → form feed
\r  → carriage return
\"  → double quote
\'  → single quote
\\  → backslash
\uXXXX → Unicode character

2. Numbers

Integers and decimals:

<!-- Integers -->
${42}
${-10}

<!-- Decimals -->
${3.14}
${-0.5}

<!-- Scientific notation -->
${1.5e10}
${2E-3}

Practical example:

<div class="price">
  <!-- Original price -->
  <span class="original">${99.99}</span>

  <!-- Discount percentage -->
  <span class="discount">${20}% OFF</span>

  <!-- Final price -->
  <span class="final">${79.99}</span>
</div>

3. Booleans

Values true and false:

${true}
${false}

4. Arrays

Lists of values in square brackets:

${['first', 'second', 'third']}
${[1, 2, 3, 4, 5]}
${[true, false, true]}

Accessing elements:

<!-- First element (index 0) -->
${myArray[0]}

<!-- Second element -->
${myArray[1]}

<!-- With variable as index -->
${myArray[index]}

Property Access

Dot Notation

<!-- Property access -->
${properties.title}

<!-- Nested access -->
${currentPage.properties.jcr:title}

<!-- Warning: NO spaces! -->
${object.property}  ✓ Correct
${object . property}  ✗ Error

Bracket Notation

Useful for:

  • Properties with special characters
  • Properties with spaces
  • Dynamic access
<!-- Property with colons -->
${properties['jcr:title']}

<!-- Property with spaces (allowed here!) -->
${object['my property']}

<!-- Dynamic access -->
${object[variableName]}

Practical example:

<div data-sly-use.model="com.example.ProductModel">
  <!-- Dot notation -->
  <h2>${model.productName}</h2>

  <!-- Bracket notation with variable -->
  <p>${model[fieldName]}</p>

  <!-- JCR property -->
  <time>${properties['jcr:created']}</time>
</div>

Automatic Casting

HTL automatically converts values:

To String

<!-- Number → String -->
${'You have ' + 5 + ' messages'}
<!-- Output: "You have 5 messages" -->

<!-- Boolean → String -->
${'Active: ' + true}
<!-- Output: "Active: true" -->

To Boolean

Falsy values (considered false):

  • false
  • 0 or 0.0
  • Empty string ""
  • Empty array []

All other values are truthy (considered true).

<!-- Only if title is not empty -->
<h1 data-sly-test="${properties.title}">
  ${properties.title}
</h1>

<!-- Only if count is > 0 -->
<div data-sly-test="${properties.count}">
  ${properties.count} items
</div>

Empty Expressions

An empty expression is valid and produces no output:

${}
<!-- Output: nothing -->

Complete Example: Product Card

<div class="product-card" data-sly-use.product="com.example.ProductModel">
  <!-- Title -->
  <h3>${product.name}</h3>

  <!-- Description (property with spaces) -->
  <p>${product['long description']}</p>

  <!-- Price -->
  <div class="price">
    <span class="currency">${'€'}</span>
    <span class="amount">${product.price}</span>
  </div>

  <!-- Availability -->
  <p class="stock">
    ${'In stock: ' + product.stockCount}
  </p>

  <!-- Rating (array) -->
  <div class="rating">
    ${product.ratings[0]} stars
  </div>

  <!-- JCR property -->
  <time datetime="${properties['jcr:created']}">
    Created: ${properties['jcr:created']}
  </time>
</div>

Expression Escaping

To display ${ literally without evaluating it:

\${this.will.not.be.evaluated}
<!-- Output: ${this.will.not.be.evaluated} -->

Best Practices

  1. Use dot notation when possible: more readable
  2. Bracket notation for JCR properties: ${properties['jcr:title']}
  3. Don't perform complex operations in expressions: move them to Sling Model
  4. Leverage automatic casting: data-sly-test="${variable}" is enough

Practical Exercises

Try creating these components:

  1. User Profile: Display name, email and avatar from properties
  2. Counter: Display a number and its square
  3. List Preview: Display the first 3 elements of an array

Next Lesson

In the next lesson we'll learn about logical, comparison and relational operators to create more complex expressions.


Lesson #2 of the HTL Tutorial series. ← Previous lesson | Next lesson →