HTL Tutorial #5: data-sly-text - Content Output
HTL Tutorial #5: data-sly-text - Content Output
What is data-sly-text?
data-sly-text is a block statement that replaces all content of an HTML element with the value of the expression.
Basic Syntax
<element data-sly-text="${expression}">
This content will be replaced
</element>Comparison with Inline Expressions
Inline Expression ${...}
<h1>${properties.title}</h1>Output:
<h1>My Title</h1>data-sly-text
<h1 data-sly-text="${properties.title}">
Placeholder title
</h1>Output:
<h1>My Title</h1>Identical result, but with data-sly-text:
- ✓ You can have a visible placeholder in edit mode
- ✓ Clearer when the entire content is being replaced
- ✓ Better compatibility with some preview tools
When to Use data-sly-text
1. Placeholders for Authors
In AEM edit mode, the author sees the placeholder:
<h2 data-sly-text="${properties.subtitle}">
[Insert a subtitle here]
</h2>In Edit Mode: Sees [Insert a subtitle here]
In Published: Sees the actual value from properties.subtitle
2. Complete Element Content
When the element contains ONLY the expression:
<!-- Clearer with data-sly-text -->
<p data-sly-text="${properties.description}"></p>
<!-- Equivalent but less explicit -->
<p>${properties.description}</p>3. HTML5 Compatibility
Some HTML preview tools don't recognize ${...}:
<!-- Better for static preview -->
<span data-sly-text="${user.name}">User Name</span>
<!-- ${user.name} might not work in some tools -->
<span>${user.name}</span>Practical Examples
Example 1: User Card
<div class="user-card" data-sly-use.user="com.example.UserModel">
<!-- Name with placeholder -->
<h3 data-sly-text="${user.name}">
Placeholder Name
</h3>
<!-- Email -->
<p class="email" data-sly-text="${user.email}">
email@placeholder.com
</p>
<!-- Role -->
<span class="badge" data-sly-text="${user.role}">
Role
</span>
</div>In Edit Mode (before the author fills it):
<div class="user-card">
<h3>Placeholder Name</h3>
<p class="email">email@placeholder.com</p>
<span class="badge">Role</span>
</div>After completion:
<div class="user-card">
<h3>John Smith</h3>
<p class="email">john.smith@example.com</p>
<span class="badge">Administrator</span>
</div>Example 2: Breadcrumb
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/" data-sly-text="${'Home'}">Home</a>
</li>
<li class="breadcrumb-item">
<a href="${currentPage.parent.path}"
data-sly-text="${currentPage.parent.title}">
Parent Category
</a>
</li>
<li class="breadcrumb-item active"
data-sly-text="${currentPage.title}">
Current Page
</li>
</ol>
</nav>Example 3: Product Table
<table class="product-table" data-sly-use.products="com.example.ProductsModel">
<thead>
<tr>
<th>Product</th>
<th>Price</th>
<th>Stock</th>
</tr>
</thead>
<tbody data-sly-list.product="${products.items}">
<tr>
<!-- Product name -->
<td data-sly-text="${product.name}">
Product Name
</td>
<!-- Price with formatting -->
<td data-sly-text="${'$ ' + product.price}">
$ 0.00
</td>
<!-- Stock with conditional color -->
<td class="${product.stock > 10 ? 'text-success' : 'text-warning'}"
data-sly-text="${product.stock}">
0
</td>
</tr>
</tbody>
</table>Automatic Escaping
Like all HTL expressions, data-sly-text applies automatic HTML escaping:
<!-- Input with HTML -->
${properties.content} <!-- "<script>alert('xss')</script>" -->
<!-- Escaped output -->
<p data-sly-text="${properties.content}">
Placeholder
</p>
<!-- Result -->
<p><script>alert('xss')</script></p>If you want to preserve HTML (from a safe source), use context='html':
<div data-sly-text="${properties.richText @ context='html'}">
Placeholder
</div>Context Options
data-sly-text supports all context options:
<!-- Text context - encodes everything -->
<pre data-sly-text="${properties.code @ context='text'}">
Code placeholder
</pre>
<!-- Number context - only numbers -->
<span data-sly-text="${properties.age @ context='number'}">
0
</span>
<!-- HTML context - preserves safe HTML -->
<div data-sly-text="${properties.richContent @ context='html'}">
<p>Placeholder</p>
</div>Combination with Other Statements
data-sly-text can be combined with other data-sly-*:
With data-sly-test
<!-- Show only if title exists -->
<h2 data-sly-test="${properties.title}"
data-sly-text="${properties.title}">
Title Placeholder
</h2>With data-sly-list
<ul data-sly-list.tag="${properties.tags}">
<!-- text + list -->
<li data-sly-text="${tag}">Tag</li>
</ul>With data-sly-element
<!-- Dynamic tag + content -->
<div data-sly-element="${properties.headingLevel}"
data-sly-text="${properties.heading}">
Heading Placeholder
</div>
<!-- If headingLevel = "h2" -->
<h2>My Heading</h2>When NOT to Use data-sly-text
1. Mixed Content
<!-- ❌ WRONG - overwrites everything! -->
<p data-sly-text="${properties.name}">
Welcome, <strong>placeholder</strong>!
</p>
<!-- Output: overwrites "Welcome, <strong>" -->
<!-- ✓ CORRECT - use inline expression -->
<p>
Welcome, <strong data-sly-text="${properties.name}">placeholder</strong>!
</p>2. Multiple Outputs in the Same Element
<!-- ❌ WRONG -->
<p data-sly-text="${properties.firstName + ' ' + properties.lastName}">
First Last
</p>
<!-- ✓ CORRECT - more flexible -->
<p>
<span data-sly-text="${properties.firstName}">First</span>
<span data-sly-text="${properties.lastName}">Last</span>
</p>Block Statement Priority
If you use multiple data-sly-* on the same element, the execution order is:
data-sly-usedata-sly-testdata-sly-list/data-sly-repeatdata-sly-textdata-sly-attributedata-sly-elementdata-sly-unwrap
<p data-sly-test="${properties.show}"
data-sly-text="${properties.content}">
Placeholder
</p>
<!-- 1. Checks test 2. If true, applies text -->Best Practices
- Use meaningful placeholders: they help authors
- Prefer inline
${...}for simple content - Use
data-sly-textwhen:- You want visible placeholders
- The element contains only that output
- Better compatibility with external tools
- Combine with
data-sly-testfor conditional content - Pay attention to context: specify when necessary
Practical Exercises
- Author Profile: Card with name, bio, email using
data-sly-textand placeholders - Product List: Table with name, price, availability
- Meta Info: Display publication date, author, category with placeholders
Next Lesson
In the next lesson we'll discover data-sly-test for conditional rendering and how to show/hide elements based on conditions.
Lesson #5 of the HTL Tutorial series. ← Previous lesson | Next lesson →