HTL Tutorial #3: Operatori Logici, Confronto e Relazionali

HTL Tutorial #3: Operatori Logici, Confronto e Relazionali

Operatori Logici

AND Logico &&

Entrambe le condizioni devono essere vere:

<!-- Mostra solo se title E author esistono -->
<div data-sly-test="${properties.title && properties.author}">
  <h2>${properties.title}</h2>
  <p>di ${properties.author}</p>
</div>

OR Logico ||

Almeno una condizione deve essere vera:

<!-- Mostra il titolo da properties OPPURE da pageProperties -->
<h1>${properties.title || pageProperties.title}</h1>

<!-- Fallback multipli -->
<p>${properties.description || properties.text || 'Nessuna descrizione disponibile'}</p>

Esempio pratico: Immagine con fallback

<!-- Usa customImage, altrimenti defaultImage, altrimenti placeholder -->
<img src="${properties.customImage || properties.defaultImage || '/images/placeholder.jpg'}"
     alt="${properties.altText || 'Immagine'}">

NOT Logico !

Nega (inverte) una condizione:

<!-- Mostra solo se NON è in modalità edit -->
<div data-sly-test="${!wcmmode.edit}">
  Contenuto visibile solo in preview/publish
</div>

<!-- Mostra messaggio solo se NON ci sono risultati -->
<p data-sly-test="${!results}">
  Nessun risultato trovato
</p>

Combinazioni di Operatori

<!-- (A AND B) OR C -->
<div data-sly-test="${(properties.premium && user.subscribed) || user.isAdmin}">
  Contenuto premium
</div>

<!-- NOT (A OR B) -->
<div data-sly-test="${!(properties.hidden || properties.draft)}">
  Contenuto pubblicato
</div>

Operatori di Confronto

Uguaglianza ==

Verifica se due valori sono uguali:

<!-- Confronto stringhe -->
<div data-sly-test="${properties.status == 'published'}">
  <span class="badge">Pubblicato</span>
</div>

<!-- Confronto numeri -->
<div data-sly-test="${properties.rating == 5}">
  ⭐⭐⭐⭐⭐
</div>

<!-- Confronto booleani -->
<div data-sly-test="${properties.featured == true}">
  <span class="featured-badge">In evidenza</span>
</div>

Disuguaglianza !=

Verifica se due valori sono diversi:

<!-- Mostra solo se status NON è 'draft' -->
<article data-sly-test="${properties.status != 'draft'}">
  ${properties.content}
</article>

<!-- Nascondi elementi con priorità 0 -->
<div data-sly-test="${properties.priority != 0}">
  Priorità: ${properties.priority}
</div>

Minore < e Minore o Uguale <=

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

<!-- Sconto per ordini piccoli -->
<p data-sly-test="${cart.total <= 50}">
  Spedizione gratuita sopra €50
</p>

Maggiore > e Maggiore o Uguale >=

<!-- Badge per utenti esperti -->
<span data-sly-test="${user.points > 1000}" class="badge-gold">
  Utente Gold
</span>

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

Esempio pratico: Sistema di rating

<div class="rating" data-sly-use.product="com.example.ProductModel">
  <!-- Eccellente -->
  <span data-sly-test="${product.rating >= 4.5}" class="excellent">
    ⭐⭐⭐⭐⭐ Eccellente
  </span>

  <!-- Buono -->
  <span data-sly-test="${product.rating >= 3.5 && product.rating < 4.5}" class="good">
    ⭐⭐⭐⭐ Buono
  </span>

  <!-- Medio -->
  <span data-sly-test="${product.rating >= 2.5 && product.rating < 3.5}" class="average">
    ⭐⭐⭐ Medio
  </span>

  <!-- Scarso -->
  <span data-sly-test="${product.rating < 2.5}" class="poor">
    ⭐⭐ Da migliorare
  </span>
</div>

Operatore Relazionale in

L'operatore in verifica l'appartenenza e supporta diversi casi d'uso:

1. Substring in Stringa

<!-- Verifica se 'java' è contenuto in description -->
<div data-sly-test="${'java' in properties.description}">
  Questo post parla di Java
</div>

<!-- Case-sensitive! -->
<p data-sly-test="${'@gmail.com' in user.email}">
  Utente Gmail
</p>

2. Elemento in Array

<!-- Verifica se 'htl' è nell'array tags -->
<div data-sly-test="${'htl' in properties.tags}">
  Tag HTL presente
</div>

<!-- Con numeri -->
<div data-sly-test="${5 in properties.allowedValues}">
  Valore 5 è permesso
</div>

3. Proprietà in Oggetto

<!-- Verifica se esiste la proprietà 'email' -->
<div data-sly-test="${'email' in user}">
  <a href="mailto:${user.email}">Contatta</a>
</div>

<!-- Verifica proprietà complesse -->
<div data-sly-test="${'socialMedia' in properties}">
  <!-- Social links disponibili -->
</div>

Esempio pratico: Tag Filter

<div class="post-badges" data-sly-use.post="com.example.PostModel">
  <!-- Badge se contiene specifici tag -->
  <span data-sly-test="${'featured' in post.tags}" class="badge-featured">
    In evidenza
  </span>

  <span data-sly-test="${'tutorial' in post.tags}" class="badge-tutorial">
    Tutorial
  </span>

  <span data-sly-test="${'advanced' in post.tags}" class="badge-advanced">
    Avanzato
  </span>
</div>

Operatore Ternario ? :

Condizione inline: condizione ? valoreSeVero : valoreSeFalso

<!-- Classe CSS condizionale -->
<div class="${properties.featured ? 'featured' : 'normal'}">
  Contenuto
</div>

<!-- Testo dinamico -->
<p>${user.isLoggedIn ? 'Benvenuto ' + user.name : 'Effettua il login'}</p>

<!-- Numero con plurale -->
<p>${itemCount == 1 ? '1 elemento' : itemCount + ' elementi'}</p>

Esempio pratico: Status Badge

<span class="status-badge ${properties.status == 'active' ? 'badge-success' : 'badge-danger'}">
  ${properties.status == 'active' ? '✓ Attivo' : '✗ Inattivo'}
</span>

Ternario annidato (evitare se possibile):

<!-- Funziona ma poco leggibile -->
<p>${score >= 90 ? 'Eccellente' : score >= 70 ? 'Buono' : score >= 50 ? 'Sufficiente' : 'Insufficiente'}</p>

<!-- Meglio usare data-sly-test separati! -->

Precedenza degli Operatori

Da maggiore a minore priorità:

  1. ! (NOT)
  2. <, <=, >, >=
  3. ==, !=, in
  4. && (AND)
  5. || (OR)
  6. ? : (Ternario)

Usa le parentesi per chiarezza:

<!-- Senza parentesi - potrebbe confondere -->
${a || b && c}

<!-- Con parentesi - chiaro! -->
${a || (b && c)}

Esempio Completo: Sistema di Permessi

<div data-sly-use.user="com.example.UserModel"
     data-sly-use.page="com.example.PageModel">

  <!-- Pulsante Edit: solo per admin o autore della pagina -->
  <button data-sly-test="${user.isAdmin || user.id == page.authorId}">
    Modifica
  </button>

  <!-- Pulsante Delete: solo admin -->
  <button data-sly-test="${user.isAdmin && page.status != 'published'}">
    Elimina
  </button>

  <!-- Badge Premium -->
  <div data-sly-test="${'premium' in user.roles && user.subscriptionActive}">
    <span class="badge-premium">Premium</span>
  </div>

  <!-- Messaggio status -->
  <p class="${page.published ? 'text-success' : 'text-warning'}">
    ${page.published ? 'Pagina pubblicata' : 'Bozza non pubblicata'}
  </p>

  <!-- Contatore con plurale -->
  <p>${page.commentCount == 0 ? 'Nessun commento' :
        page.commentCount == 1 ? '1 commento' :
        page.commentCount + ' commenti'}</p>
</div>

Best Practice

  1. Usa parentesi per chiarezza: ${(a && b) || c} invece di ${a && b || c}
  2. Evita ternari annidati: preferisci data-sly-test multipli
  3. Semplifica condizioni complesse: spostale nel Sling Model
  4. Attenzione al case: 'HTL' in text è diverso da 'htl' in text
  5. Operatore in è potente: usalo per array, stringhe e oggetti

Esercizi Pratici

  1. Login Status: Mostra "Benvenuto [nome]" se loggato, altrimenti "Login"
  2. Price Filter: Mostra prodotti solo se prezzo tra €10 e €100
  3. Tag Checker: Verifica se un post ha almeno 2 tag specifici

Prossima Lezione

Nella prossima lezione scopriremo il Context-Aware XSS Protection: come HTL protegge automaticamente il tuo codice da vulnerabilità di sicurezza.


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