
Syntaxe de base de Thymeleaf (expressions, itérations, conditions)
Apprenez la syntaxe essentielle de Thymeleaf : variables, sélections, liens, itérations sur collections (th:each) et affichage conditionnel (th:if, th:unless, th:switch).
Thymeleaf : intégrer la logique dans votre HTML
Thymeleaf est un moteur de template Java moderne conçu pour les environnements web et autonomes. Son principal objectif est d'apporter une élégante logique côté serveur aux fichiers HTML, tout en conservant la capacité de ces fichiers à être correctement affichés dans un navigateur comme des prototypes statiques – c'est ce qu'on appelle le "Natural Templating". Au lieu d'inventer une nouvelle syntaxe de template complexe, Thymeleaf s'appuie sur des attributs spécifiques ajoutés aux balises HTML existantes.
Ces attributs, préfixés par th: (par exemple, th:text, th:if, th:each), sont la clé pour comprendre et utiliser Thymeleaf. Lorsque le serveur traite le template HTML, Thymeleaf interprète ces attributs, exécute la logique qu'ils contiennent (accéder à des données, boucler, tester des conditions) et modifie le DOM HTML en conséquence avant de renvoyer le résultat final au navigateur. Le navigateur, lui, ignore simplement ces attributs th: s'il affiche le fichier statiquement.
Ce chapitre se concentre sur les éléments syntaxiques fondamentaux que vous utiliserez constamment : comment afficher des données dynamiques grâce aux expressions, comment parcourir des listes ou d'autres collections pour générer du contenu répétitif, et comment afficher ou masquer des parties de votre page en fonction de conditions spécifiques.
Les expressions Thymeleaf : accéder aux données et plus encore
Les expressions sont au coeur de Thymeleaf, car elles permettent d'accéder aux données préparées par votre application Spring Boot (dans l'objet Model) et de les intégrer dans le template HTML. Thymeleaf propose plusieurs types d'expressions, chacune avec une syntaxe spécifique et un but précis :
Expressions de variables : ${...}
C'est le type d'expression le plus courant. Il permet d'accéder aux variables présentes dans le contexte Thymeleaf (qui correspond généralement au Model Spring). Si votre contrôleur ajoute un attribut nommé `message` au modèle, vous pouvez l'afficher dans votre HTML comme suit :
<!-- Dans le contrôleur Spring : model.addAttribute("message", "Bienvenue sur notre site !"); -->
<p th:text="${message}">Texte de remplacement si message est null</p>
<!-- Résultat rendu : <p>Bienvenue sur notre site !</p> -->Vous pouvez également accéder aux propriétés des objets : ${utilisateur.nom}.
Expressions de sélection (ou d'astérisque) : *{...}
Ces expressions fonctionnent de manière similaire aux expressions de variables, mais elles s'appliquent à un objet préalablement sélectionné, généralement via l'attribut th:object. C'est particulièrement utile dans les formulaires pour lier les champs à un bean.
<!-- Dans le contrôleur : model.addAttribute("user", new User("John", "Doe")); -->
<form th:object="${user}">
<p>Prénom: <span th:text="*{firstName}">Prénom ici</span></p> <!-- *{firstName} équivaut à ${user.firstName} ici -->
<p>Nom: <span th:text="*{lastName}">Nom ici</span></p>
</form>Expressions de lien (URL) : @{...}
Essentielles pour créer des liens dynamiques et context-aware. Thymeleaf génère automatiquement les URLs correctes, en ajoutant le contexte path de l'application si nécessaire. Elles sont utilisées avec des attributs comme th:href ou th:src.
<!-- Lien simple -->
<a th:href="@{/produits}">Voir les produits</a>
<!-- Lien avec paramètres -->
<a th:href="@{/produits/details(id=${produit.id})}">Détails</a>
<!-- Résultat possible : <a href="/monapp/produits/details?id=123">Détails</a> -->
<!-- Lien avec variables de chemin -->
<a th:href="@{/utilisateurs/{userId}/profile(userId=${user.id})}">Profil</a>
<!-- Résultat possible : <a href="/monapp/utilisateurs/456/profile">Profil</a> -->Expressions de message (Internationalisation) : #{...}
Utilisées pour afficher du texte provenant de sources externes, typiquement des fichiers de messages (messages.properties, messages_fr.properties, etc.) pour l'internationalisation (i18n). Elles permettent de rendre votre application multilingue.
<!-- Dans messages_fr.properties: accueil.titre=Bienvenue ! -->
<h1 th:text="#{accueil.titre}">Titre par défaut</h1>
<!-- Résultat en français : <h1>Bienvenue !</h1> -->Littéraux et Opérations : Thymeleaf supporte les littéraux pour les textes ('Mon texte'), les nombres (123, 1.23), les booléens (true, false) et la valeur null. Vous pouvez également effectuer des opérations arithmétiques, logiques et de comparaison directement dans les expressions : ${user.age > 18}, ${produit.prix * 1.20}, ${user.role == 'ADMIN'}.
Parcourir les collections : itérations avec `th:each`
L'une des tâches les plus courantes dans les templates web est d'afficher une liste d'éléments provenant d'une collection (comme une liste de produits, d'utilisateurs, d'articles, etc.). Thymeleaf fournit l'attribut th:each pour gérer ces itérations de manière simple et élégante.
th:each s'applique à une balise HTML et la répète pour chaque élément de la collection spécifiée. La syntaxe de base est th:each="variableIteration : ${collection}". variableIteration est le nom que vous donnez à l'élément courant de la collection à chaque tour de boucle, et ${collection} est une expression Thymeleaf (généralement une expression de variable) qui évalue vers un objet itérable (List, Set, tableau, Map...).
// Dans le contrôleur Spring:
List<Produit> produits = ... // Récupérer la liste des produits
model.addAttribute("produits", produits);<!-- Dans le template HTML -->
<h2>Liste des produits</h2>
<ul>
<li th:each="prod : ${produits}">
<span th:text="${prod.nom}">Nom du produit</span> -
Prix: <span th:text="${prod.prix}">0.00</span> €
</li>
<!-- Si la liste est vide, la balise <li> ne sera pas rendue du tout -->
</ul>Dans cet exemple, la balise <li> sera répétée pour chaque objet Produit dans la liste produits. A chaque itération, l'objet Produit courant sera accessible via la variable prod.
Thymeleaf fournit également une variable de statut d'itération optionnelle, très utile pour obtenir des informations sur l'état de la boucle (index, compteur, premier/dernier élément, etc.). On la déclare en ajoutant une virgule après la variable d'itération : th:each="variableIteration, status : ${collection}". La variable de statut (ici nommée status, mais vous pouvez choisir un autre nom) expose plusieurs propriétés :
index: Index courant, commence à 0.count: Compteur courant, commence à 1.size: Nombre total d'éléments dans la collection.current: L'élément courant (identique àvariableIteration).even/odd: Booléens indiquant si l'itération est paire ou impaire (basé surcount).first/last: Booléens indiquant s'il s'agit de la première ou de la dernière itération.
<table>
<tr th:each="user, iterStat : ${utilisateurs}" th:class="${iterStat.odd}? 'impaire' : 'paire' ">
<td th:text="${iterStat.count}">1</td>
<td th:text="${user.username}">login</td>
</tr>
</table>Cet exemple utilise iterStat.count pour afficher le numéro de ligne et iterStat.odd pour appliquer une classe CSS différente aux lignes impaires.
Affichage conditionnel : `th:if`, `th:unless` et `th:switch`
Il est fréquent de devoir afficher ou masquer certaines parties d'une page HTML en fonction de conditions spécifiques (par exemple, afficher un lien "Admin" uniquement si l'utilisateur est administrateur, montrer un message d'erreur si une condition est remplie, etc.). Thymeleaf propose plusieurs attributs pour gérer cet affichage conditionnel.
th:if="${condition}" : C'est l'attribut conditionnel le plus utilisé. Il évalue l'expression fournie. Si l'expression est évaluée comme false, la balise HTML sur laquelle th:if est appliqué (et tout son contenu) est rendue normalement. Si l'expression est évaluée comme false, la balise (et son contenu) est complètement retirée du résultat final. Thymeleaf considère comme false les valeurs suivantes : false, 0, null, une chaîne vide, une collection ou une map vide, un tableau vide. Toute autre valeur est considérée comme true.
<!-- Dans le contrôleur : model.addAttribute("isUserLoggedIn", true); model.addAttribute("isAdmin", false); -->
<div th:if="${isUserLoggedIn}">
<p>Bienvenue, utilisateur connecté !</p>
<a th:if="${isAdmin}" href="/admin">Panneau d'administration</a> <!-- Ce lien ne sera pas affiché -->
</div>
<p th:if="${panier != null and not #lists.isEmpty(panier.items)}">
Vous avez des articles dans votre panier.
</p>th:unless="${condition}" : C'est exactement l'inverse de th:if. La balise et son contenu sont rendus uniquement si l'expression est évaluée comme false (selon les règles vues précédemment). Si l'expression est true, la balise est retirée.
<!-- Dans le contrôleur : model.addAttribute("errorMsg", null); -->
<div th:unless="${errorMsg == null}" class="error">
<p th:text="${errorMsg}">Message d'erreur ici</p>
</div>
<!-- Le div ne sera pas affiché car errorMsg est null (considéré comme false par unless) -->
<p th:unless="${isUserLoggedIn}">Veuillez vous connecter.</p>th:switch / th:case : Pour des conditions multiples, similaires à une instruction switch en Java. L'attribut th:switch est placé sur un élément parent et contient l'expression à évaluer. Chaque élément enfant peut avoir un attribut th:case="valeur". Thymeleaf rendra le premier élément th:case dont la valeur correspond au résultat de l'expression th:switch. Un cas spécial, th:case="*", agit comme le cas default et sera rendu si aucun autre th:case ne correspond.
<!-- Dans le contrôleur : model.addAttribute("userRole", "EDITOR"); -->
<div th:switch="${userRole}">
<p th:case="'ADMIN'">Accès administrateur.</p>
<p th:case="'EDITOR'">Accès éditeur.</p> <!-- Ce paragraphe sera rendu -->
<p th:case="'GUEST'">Accès invité.</p>
<p th:case="*">Rôle inconnu.</p> <!-- Cas par défaut -->
</div>Maîtriser les bases pour des vues dynamiques
Les expressions, les itérations avec th:each et les structures conditionnelles th:if, th:unless et th:switch constituent la boîte à outils fondamentale pour rendre vos pages HTML dynamiques avec Thymeleaf. En maîtrisant ces concepts, vous pouvez déjà accomplir une grande partie des tâches courantes de templating web.
La force de Thymeleaf réside dans sa capacité à intégrer cette logique directement dans des attributs HTML standard, préservant ainsi la structure et la lisibilité de vos fichiers HTML. En combinant ces éléments de base, vous pouvez créer des vues complexes qui s'adaptent aux données fournies par votre backend Spring Boot, tout en gardant une séparation claire entre la logique de présentation (dans le template) et la logique métier (dans le contrôleur et les services).
Bien sûr, Thymeleaf offre bien plus de fonctionnalités (fragments de template pour la réutilisation, layouts, traitement des formulaires, expressions utilitaires, etc.), mais une solide compréhension de ces syntaxes de base est le prérequis indispensable pour explorer efficacement le reste de cet puissant moteur de template.