HTL Tutorial #6: data-sly-test - Rendering Condizionale

HTL Tutorial #6: data-sly-test - Rendering Condizionale

Cos'è data-sly-test?

data-sly-test valuta un'espressione e:

  • Se true: renderizza l'elemento
  • Se false: rimuove completamente l'elemento dall'output

Sintassi Base

<elemento data-sly-test="${condizione}">
  Questo appare solo se condizione è true
</elemento>

Esempio Semplice

<!-- Mostra solo se title esiste -->
<h1 data-sly-test="${properties.title}">
  ${properties.title}
</h1>

Se properties.title è vuoto/null:

<!-- Nessun output - elemento completamente rimosso! -->

Se properties.title = "Benvenuto":

<h1>Benvenuto</h1>

Valori Truthy e Falsy

HTL considera falsy (= false):

  • false (booleano)
  • 0 o 0.0 (numero zero)
  • "" (stringa vuota)
  • [] (array vuoto)
  • null / undefined

Tutto il resto è truthy (= true):

  • true
  • Qualsiasi numero diverso da 0
  • Qualsiasi stringa non vuota
  • Array con elementi
  • Oggetti
<!-- ❌ NON mostra (falsy) -->
<div data-sly-test="${false}">No</div>
<div data-sly-test="${0}">No</div>
<div data-sly-test="${''}">No</div>
<div data-sly-test="${[]}">No</div>

<!-- ✓ Mostra (truthy) -->
<div data-sly-test="${true}"></div>
<div data-sly-test="${1}"></div>
<div data-sly-test="${'hello'}"></div>
<div data-sly-test="${[1,2,3]}"></div>

Condizioni con Operatori

Operatori di Confronto

<!-- Uguaglianza -->
<div data-sly-test="${user.role == 'admin'}">
  Pannello Amministratore
</div>

<!-- Maggiore/Minore -->
<div data-sly-test="${product.stock < 10}" class="alert-warning">
  Solo ${product.stock} pezzi rimasti!
</div>

<div data-sly-test="${user.age >= 18}">
  Contenuto per maggiorenni
</div>

Operatori Logici

<!-- AND: entrambe le condizioni devono essere true -->
<div data-sly-test="${user.isLoggedIn && user.isPremium}">
  Contenuto Premium
</div>

<!-- OR: almeno una deve essere true -->
<div data-sly-test="${properties.showAlways || wcmmode.edit}">
  Visibile in edit o se showAlways è true
</div>

<!-- NOT: inverte la condizione -->
<div data-sly-test="${!user.isLoggedIn}">
  <a href="/login">Effettua il login</a>
</div>

Operatore IN

<!-- Verifica se tag presente in array -->
<span data-sly-test="${'featured' in properties.tags}" class="badge-featured">
  In Evidenza
</span>

<!-- Substring in stringa -->
<div data-sly-test="${'@gmail.com' in user.email}">
  Utente Gmail
</div>

Pattern IF / ELSE

HTL non ha un costrutto else nativo, ma puoi simularlo:

Pattern 1: Negazione

<!-- IF -->
<div data-sly-test="${user.isLoggedIn}">
  <p>Benvenuto, ${user.name}!</p>
</div>

<!-- ELSE (NOT) -->
<div data-sly-test="${!user.isLoggedIn}">
  <p>Per favore <a href="/login">effettua il login</a></p>
</div>

Pattern 2: Variabile

<!-- Salva risultato test in variabile -->
<div data-sly-test.hasContent="${properties.content}">
  ${properties.content}
</div>

<!-- Usa variabile negata per else -->
<div data-sly-test="${!hasContent}">
  Nessun contenuto disponibile
</div>

Pattern 3: IF / ELSE IF / ELSE

<!-- IF -->
<div data-sly-test="${score >= 90}">
  <span class="grade-a">Eccellente!</span>
</div>

<!-- ELSE IF -->
<div data-sly-test="${score >= 70 && score < 90}">
  <span class="grade-b">Buono</span>
</div>

<!-- ELSE IF -->
<div data-sly-test="${score >= 50 && score < 70}">
  <span class="grade-c">Sufficiente</span>
</div>

<!-- ELSE -->
<div data-sly-test="${score < 50}">
  <span class="grade-f">Insufficiente</span>
</div>

Salvare il Risultato in Variabile

La sintassi data-sly-test.varName salva il risultato del test:

<!-- Test E salva in variabile -->
<div data-sly-test.isAdmin="${user.role == 'admin'}">
  <!-- isAdmin è ora disponibile -->
  <p>Modalità Admin: ${isAdmin}</p>
</div>

<!-- La variabile NON esiste fuori dal blocco -->

Uso avanzato - salva oggetto non-null:

<!-- Se user esiste, salvalo in variabile -->
<div data-sly-test.currentUser="${user}">
  <!-- currentUser è disponibile qui -->
  <h2>${currentUser.name}</h2>
  <p>${currentUser.email}</p>
</div>

Esempi Pratici Completi

Esempio 1: Navigation Menu

<nav data-sly-use.nav="com.example.NavigationModel">
  <ul class="menu">
    <!-- Mostra Home solo se non siamo in home -->
    <li data-sly-test="${currentPage.path != '/'}">
      <a href="/">Home</a>
    </li>

    <!-- Menu items da model -->
    <li data-sly-list.item="${nav.items}">
      <!-- Evidenzia pagina corrente -->
      <a href="${item.url}"
         class="${currentPage.path == item.url ? 'active' : ''}">
        ${item.title}
      </a>
    </li>

    <!-- Login/Logout condizionale -->
    <li data-sly-test="${!user.isLoggedIn}">
      <a href="/login">Login</a>
    </li>

    <li data-sly-test="${user.isLoggedIn}">
      <a href="/logout">Logout (${user.name})</a>
    </li>
  </ul>
</nav>

Esempio 2: Product Card con Badges

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

  <!-- Badge "Nuovo" se pubblicato da meno di 7 giorni -->
  <span data-sly-test="${product.daysOld < 7}" class="badge-new">
    Nuovo!
  </span>

  <!-- Badge "In Sconto" -->
  <span data-sly-test="${product.hasDiscount}" class="badge-discount">
    -${product.discountPercent}%
  </span>

  <!-- Badge "Esaurito" -->
  <div data-sly-test="${product.stock == 0}" class="out-of-stock">
    <strong>Esaurito</strong>
  </div>

  <!-- Pulsante acquisto solo se disponibile -->
  <button data-sly-test="${product.stock > 0}" class="btn-buy">
    Aggiungi al carrello
  </button>

  <!-- Alert scorte basse -->
  <div data-sly-test="${product.stock > 0 && product.stock < 5}"
       class="alert-warning">
    Solo ${product.stock} pezzi rimasti!
  </div>
</div>

Esempio 3: User Dashboard

<div class="dashboard" data-sly-use.user="com.example.UserModel">
  <!-- Salva isAdmin in variabile -->
  <div data-sly-test.isAdmin="${user.role == 'admin'}"></div>

  <!-- Header con nome -->
  <h1>Benvenuto, ${user.name}</h1>

  <!-- Stats generali -->
  <div class="stats">
    <div class="stat">
      <strong>${user.postCount}</strong>
      <span>${user.postCount == 1 ? 'post' : 'posts'}</span>
    </div>
  </div>

  <!-- Sezione Admin -->
  <section data-sly-test="${isAdmin}" class="admin-panel">
    <h2>Pannello Amministrazione</h2>
    <!-- contenuto admin -->
  </section>

  <!-- Sezione Moderatore -->
  <section data-sly-test="${user.role == 'moderator' || isAdmin}">
    <h2>Strumenti Moderazione</h2>
    <!-- contenuto moderazione -->
  </section>

  <!-- Messaggio per utenti base -->
  <div data-sly-test="${user.role == 'user' && !user.isPremium}">
    <p>
      <a href="/premium">Passa a Premium</a> per più funzionalità!
    </p>
  </div>

  <!-- Badge Premium -->
  <div data-sly-test="${user.isPremium}" class="premium-badge">
    ✨ Utente Premium
  </div>
</div>

Esempio 4: Alert System

<div class="alerts" data-sly-use.system="com.example.SystemModel">
  <!-- Error -->
  <div data-sly-test="${system.hasErrors}" class="alert alert-danger">
    <strong>Errore!</strong> ${system.errorMessage}
  </div>

  <!-- Warning -->
  <div data-sly-test="${system.hasWarnings && !system.hasErrors}"
       class="alert alert-warning">
    <strong>Attenzione:</strong> ${system.warningMessage}
  </div>

  <!-- Success -->
  <div data-sly-test="${system.hasSuccess && !system.hasErrors && !system.hasWarnings}"
       class="alert alert-success">
    <strong>Successo!</strong> ${system.successMessage}
  </div>

  <!-- Info (default) -->
  <div data-sly-test="${!system.hasErrors && !system.hasWarnings && !system.hasSuccess}"
       class="alert alert-info">
    Tutto ok, nessuna notifica.
  </div>
</div>

Combinazione con Altri Statements

Con data-sly-text

<p data-sly-test="${properties.description}"
   data-sly-text="${properties.description}">
  Placeholder description
</p>

Con data-sly-list

<!-- Lista solo se ha elementi -->
<ul data-sly-test="${properties.items}"
    data-sly-list.item="${properties.items}">
  <li>${item}</li>
</ul>

Con data-sly-attribute

<!-- Attributo condizionale -->
<div data-sly-test="${properties.customId}"
     data-sly-attribute.id="${properties.customId}">
  Contenuto
</div>

Best Practice

  1. Preferisci valutazioni semplici: ${variable} invece di ${variable != null}
  2. Usa variabili per condizioni complesse: data-sly-test.varName
  3. Pattern ELSE con negazione: ${!condition}
  4. Combina con altri statement quando ha senso
  5. Test su esistenza prima di accedere: evita errori
  6. Sfrutta truthy/falsy: codice più pulito

Errori Comuni

❌ Test su stringa letterale

<!-- SBAGLIATO - sempre true! -->
<div data-sly-test="${'false'}">
  Questo appare sempre!
</div>

❌ Confondere = con ==

<!-- SBAGLIATO - assegnazione non supportata -->
<div data-sly-test="${user.role = 'admin'}">

<!-- CORRETTO - confronto -->
<div data-sly-test="${user.role == 'admin'}">

❌ Accedere a variabile fuori scope

<div data-sly-test.myVar="${something}">
  ${myVar} <!-- OK -->
</div>
${myVar} <!-- ERRORE - fuori scope! -->

Esercizi Pratici

  1. Login Widget: Mostra form login se non loggato, altrimenti dashboard utente
  2. Product Filter: Mostra prodotti solo se prezzo tra min e max
  3. Access Control: Pannello admin visibile solo per admin, moderatori hanno accesso parziale

Prossima Lezione

Nella prossima lezione scopriremo data-sly-list e data-sly-repeat per iterare su array e collezioni.


Lezione #6 della serie HTL Tutorial. ← Lezione precedente | Lezione successiva →