HTL Tutorial #1: Introduzione a HTML Template Language

HTL Tutorial #1: Introduzione a HTML Template Language

Cos'è HTL?

HTL (HTML Template Language), precedentemente chiamato Sightly, è il sistema di templating raccomandato e preferito per Adobe Experience Manager (AEM).

Perché HTL?

  1. Sicurezza integrata: Protezione automatica contro XSS (Cross-Site Scripting)
  2. Semplicità: Sintassi HTML-like, facile da leggere e scrivere
  3. Separazione logica/presentazione: La logica complessa va in Java/JS, non nel template
  4. Performance: Compilato in Java Servlets per esecuzione server-side efficiente
  5. Designer-friendly: I designer possono lavorare con HTML senza conoscere Java

Sintassi Base

HTL utilizza due costrutti principali:

1. Espressioni ${...}

Le espressioni HTL sono racchiuse tra ${ e }:

<h1>${properties.title}</h1>

Output:

<h1>Benvenuto nel mio sito</h1>

2. Attributi data-sly-*

Gli attributi HTL iniziano con data-sly- e controllano il comportamento dell'elemento:

<div data-sly-test="${properties.showContent}">
  <p>Questo contenuto viene mostrato solo se showContent è true</p>
</div>

Primo Esempio Completo

Creiamo un semplice componente HTL per visualizzare informazioni di un autore:

<!--/* Componente Autore Semplice */-->
<div class="author-card">
  <!-- Titolo con espressione -->
  <h2>${properties.authorName}</h2>

  <!-- Paragrafo condizionale -->
  <p data-sly-test="${properties.bio}">${properties.bio}</p>

  <!-- Link solo se presente -->
  <a data-sly-test="${properties.website}"
     href="${properties.website}">
    Visita il sito
  </a>
</div>

Dati del componente (dialog)

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" 
          xmlns:cq="http://www.day.com/jcr/cq/1.0" 
          xmlns:jcr="http://www.jcp.org/jcr/1.0" 
          xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
          xmlns:granite="http://www.adobe.com/jcr/granite/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Proprietà Autore"
    sling:resourceType="cq/gui/components/authoring/dialog">
    
    <content
        jcr:primaryType="nt:unstructured"
        sling:resourceType="granite/ui/components/coral/foundation/container">
        
        <layout
            jcr:primaryType="nt:unstructured"
            sling:resourceType="granite/ui/components/coral/foundation/tabs"
            type="nav"/>
        
        <items jcr:primaryType="nt:unstructured">
            
            <properties
                jcr:primaryType="nt:unstructured"
                jcr:title="Informazioni Autore"
                sling:resourceType="granite/ui/components/coral/foundation/container">
                
                <layout
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="granite/ui/components/coral/foundation/layouts/fixedcolumn"
                    margin="{Boolean}false"/>
                
                <items jcr:primaryType="nt:unstructured">
                    
                    <column
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/coral/foundation/container">
                        
                        <items jcr:primaryType="nt:unstructured">
                            
                            <authorName
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                fieldLabel="Nome Autore"
                                name="./authorName"
                                required="{Boolean}true"/>
                            
                            <bio
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/form/textarea"
                                fieldLabel="Biografia"
                                name="./bio"/>
                            
                            <website
                                jcr:primaryType="nt:unstructured"
                                sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                                fieldLabel="Sito Web"
                                name="./website"
                                validation="url"/>
                                
                        </items>
                    </column>
                </items>
            </properties>
            
            </items>
    </content>
</jcr:root>

Output HTML

Con i dati:

<div class="author-card">
  <h2>Mario Rossi</h2>
  <p>Sviluppatore AEM senior</p>
  <a href="https://mariorossi.it">Visita il sito</a>
</div>

Commenti HTL

HTL ha un tipo speciale di commento che viene rimosso completamente dall'output:

<!--/* Questo è un commento HTL */-->
<!--/*
  Commento multi-linea
  Non apparirà nell'HTML finale
*/-->

Differenza con commenti HTML normali:

<!-- Questo appare nell'output HTML -->
<!--/* Questo viene rimosso completamente */-->

Confronto con JSP

JSP (vecchio modo):

<h1><%= properties.get("title", "") %></h1>
<% if (properties.get("showContent", false)) { %>
  <p>Contenuto</p>
<% } %>

HTL (nuovo modo):

<h1>${properties.title}</h1>
<p data-sly-test="${properties.showContent}">Contenuto</p>

HTL è più pulito, più sicuro e più leggibile!

Best Practice di Base

  1. Usa sempre espressioni per l'output: ${...}
  2. Non mettere logica complessa nel template: usa data-sly-use per caricare modelli Java
  3. Sfrutta la sicurezza automatica: HTL escapa automaticamente l'output
  4. Commenta il codice: usa <!--/* */--> per documentare i template

Prossima Lezione

Nella prossima lezione approfondiremo le espressioni HTL, i tipi di dato e gli operatori disponibili.

Risorse


Questa è la lezione #1 di una serie completa su HTL. Continua con la lezione successiva per approfondire le espressioni e la sintassi.