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 character2. 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} ✗ ErrorBracket 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):
false0or0.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
- Use dot notation when possible: more readable
- Bracket notation for JCR properties:
${properties['jcr:title']} - Don't perform complex operations in expressions: move them to Sling Model
- Leverage automatic casting:
data-sly-test="${variable}"is enough
Practical Exercises
Try creating these components:
- User Profile: Display name, email and avatar from
properties - Counter: Display a number and its square
- 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 →