HTL Tutorial #10: data-sly-attribute - Manipolare Attributi HTML
HTL Tutorial #10: data-sly-attribute - Manipolare Attributi HTML
Cos'è data-sly-attribute?
data-sly-attribute permette di manipolare dinamicamente gli attributi HTML: aggiungere, modificare o rimuovere attributi basandosi su condizioni o dati.
Sintassi Base
Singolo Attributo
<div data-sly-attribute.nomeAttributo="${valore}">
Contenuto
</div>Multipli Attributi
<div data-sly-attribute="${oggetto}">
Contenuto
</div>Esempi Semplici
Aggiungere un Attributo
<!-- Aggiunge data-id dinamicamente -->
<div data-sly-attribute.data-id="${product.id}">
${product.name}
</div>Output:
<div data-id="12345">
Laptop
</div>Modificare Attributo Esistente
<!-- Override dell'attributo class -->
<div class="card" data-sly-attribute.class="${'card ' + product.status}">
Contenuto
</div>Output (se product.status = 'active'):
<div class="card active">
Contenuto
</div>Rimuovere un Attributo
Se il valore è null, false, o stringa vuota, l'attributo viene rimosso:
<div title="Default title"
data-sly-attribute.title="${properties.customTitle}">
Hover me
</div>Se properties.customTitle è null:
<div>
Hover me
</div>Se properties.customTitle = 'Custom':
<div title="Custom">
Hover me
</div>Attributi Multipli con Oggetto
Puoi passare un oggetto per impostare multipli attributi in una volta:
<div data-sly-use.attrs="com.example.AttributesModel"
data-sly-attribute="${attrs.htmlAttributes}">
Contenuto
</div>Java Model:
@Model(adaptables = Resource.class)
public class AttributesModel {
public Map<String, String> getHtmlAttributes() {
Map<String, String> attrs = new HashMap<>();
attrs.put("data-id", "123");
attrs.put("data-type", "product");
attrs.put("role", "article");
return attrs;
}
}Output:
<div data-id="123" data-type="product" role="article">
Contenuto
</div>Pattern Comuni
1. Classi CSS Condizionali
<div class="card"
data-sly-attribute.class="${'card ' +
(product.featured ? 'featured ' : '') +
(product.onSale ? 'on-sale' : '')}">
${product.name}
</div>Output (featured=true, onSale=false):
<div class="card featured">
Laptop
</div>2. Attributi Data Dinamici
<div data-sly-use.product="com.example.ProductModel"
data-sly-attribute.data-product-id="${product.id}"
data-sly-attribute.data-price="${product.price}"
data-sly-attribute.data-category="${product.category}">
${product.name}
</div>Output:
<div data-product-id="123" data-price="99.99" data-category="electronics">
Laptop
</div>3. ARIA Attributes per Accessibilità
<button data-sly-attribute.aria-expanded="${menu.isOpen}"
data-sly-attribute.aria-controls="${menu.panelId}">
Menu
</button>
<div data-sly-attribute.id="${menu.panelId}"
data-sly-attribute.aria-hidden="${!menu.isOpen}">
<!-- Menu content -->
</div>4. Link con Target Condizionale
<a href="${link.url}"
data-sly-attribute.target="${link.external ? '_blank' : ''}"
data-sly-attribute.rel="${link.external ? 'noopener noreferrer' : ''}">
${link.title}
</a>Output (link esterno):
<a href="https://example.com" target="_blank" rel="noopener noreferrer">
Visita esempio
</a>Output (link interno - attributi rimossi):
<a href="/about">
Chi siamo
</a>Combinare con Altri Statement
Con data-sly-test
<div data-sly-test="${properties.customId}"
data-sly-attribute.id="${properties.customId}">
<!-- Solo se customId esiste, viene aggiunto l'attributo -->
</div>Con data-sly-list
<ul data-sly-list.item="${properties.items}">
<li data-sly-attribute.class="${itemList.first ? 'first' : ''}
${itemList.last ? 'last' : ''}">
${item}
</li>
</ul>Attributi Booleani HTML5
Per attributi booleani HTML5 come disabled, checked, readonly:
<!-- ✓ CORRETTO - usa true/false -->
<input type="checkbox"
data-sly-attribute.checked="${user.subscribed}">
<!-- Se user.subscribed = true -->
<input type="checkbox" checked>
<!-- Se user.subscribed = false -->
<input type="checkbox"><button data-sly-attribute.disabled="${!product.available}">
Acquista
</button>
<!-- Se available = false -->
<button disabled>Acquista</button>
<!-- Se available = true -->
<button>Acquista</button>Esempio Completo: Image Component
<div data-sly-use.image="com.example.ImageModel" class="image-wrapper">
<img src="${image.src}"
data-sly-attribute.alt="${image.alt}"
data-sly-attribute.title="${image.title}"
data-sly-attribute.width="${image.width}"
data-sly-attribute.height="${image.height}"
data-sly-attribute.loading="${imageList.first ? '' : 'lazy'}"
data-sly-attribute.class="${'responsive-image ' + (image.rounded ? 'rounded' : '')}"
data-sly-attribute.data-caption="${image.caption}">
<!-- Caption solo se presente -->
<p data-sly-test="${image.caption}" class="caption">
${image.caption}
</p>
</div>Output (con tutti i dati):
<div class="image-wrapper">
<img src="/content/dam/image.jpg"
alt="Descrizione immagine"
title="Titolo immagine"
width="800"
height="600"
loading="lazy"
class="responsive-image rounded"
data-caption="Foto scattata nel 2025">
<p class="caption">Foto scattata nel 2025</p>
</div>Esempio Completo: Form Input
<div data-sly-use.field="com.example.FormFieldModel">
<input type="${field.type}"
name="${field.name}"
data-sly-attribute.id="${field.id}"
data-sly-attribute.value="${field.value}"
data-sly-attribute.placeholder="${field.placeholder}"
data-sly-attribute.required="${field.required}"
data-sly-attribute.disabled="${field.disabled}"
data-sly-attribute.minlength="${field.minLength}"
data-sly-attribute.maxlength="${field.maxLength}"
data-sly-attribute.pattern="${field.pattern}"
data-sly-attribute.aria-label="${field.label}"
data-sly-attribute.aria-describedby="${field.hasError ? field.errorId : ''}"
data-sly-attribute.class="${'form-control ' + (field.hasError ? 'is-invalid' : '')}">
<!-- Error message -->
<div data-sly-test="${field.hasError}"
data-sly-attribute.id="${field.errorId}"
class="invalid-feedback">
${field.errorMessage}
</div>
</div>Attributi Speciali
href e src - URI Context
HTL applica automaticamente context='uri' a href e src:
<a href="${link.url}">Link</a>
<!-- Automaticamente protetto contro javascript:, data:, etc -->
<!-- Equivalente a: -->
<a data-sly-attribute.href="${link.url @ context='uri'}">Link</a>style Attribute
<div data-sly-attribute.style="${'background-color: ' + theme.bgColor +
'; color: ' + theme.textColor}">
Styled content
</div>Attenzione: Preferisci classi CSS quando possibile!
Best Practice
- Rimuovi attributi vuoti: HTL lo fa automaticamente con
null/false/"" - Context automatico: Non serve specificare
@ context='uri'per href/src - Attributi booleani: Usa
true/falsedirettamente - Classi CSS: Preferisci classi CSS a style inline
- ARIA attributes: Usa per accessibilità
- Data attributes: Perfetti per JavaScript hooks
- Oggetti per multipli attributi: Più pulito quando hai tanti attributi
Priorità degli Attributi
Se un attributo è definito sia nell'HTML che con data-sly-attribute, vince data-sly-attribute:
<div class="original"
data-sly-attribute.class="${'new-class'}">
Contenuto
</div>
<!-- Output: -->
<div class="new-class">
Contenuto
</div>Per preservare e aggiungere:
<div class="original"
data-sly-attribute.class="${'original ' + additionalClass}">
Contenuto
</div>Errori Comuni
❌ Nome attributo errato
<!-- SBAGLIATO - usa data-sly-attribute.nome -->
<div data-sly-attribute="data-id"="${value}">
<!-- CORRETTO -->
<div data-sly-attribute.data-id="${value}">❌ Dimenticare il punto
<!-- SBAGLIATO - manca il . -->
<div data-sly-attributeclass="${value}">
<!-- CORRETTO -->
<div data-sly-attribute.class="${value}">❌ Attributi booleani con stringhe
<!-- SBAGLIATO - usa true/false -->
<input data-sly-attribute.disabled="${'disabled'}">
<!-- CORRETTO -->
<input data-sly-attribute.disabled="${true}">Esercizi Pratici
- Card Component: Crea card con attributi dinamici (id, data-*, class)
- Link List: Lista di link con target="_blank" solo per esterni
- Form Builder: Form con validazione e ARIA attributes
- Image Gallery: Gallery con lazy loading e attributi dimensionali
Prossima Lezione
Nella prossima lezione vedremo data-sly-element per cambiare dinamicamente il tag HTML di un elemento.
Lezione #10 della serie HTL Tutorial. ← Lezione precedente | Lezione successiva →