
Héritage de templates (`extends`, `block`) pour une structure cohérente
Maîtrisez l'héritage de templates dans Twig avec les tags `extends` et `block`. Apprenez à créer des layouts de base réutilisables et à construire des pages web cohérentes et faciles à maintenir dans Symfony.
Introduction à l'héritage de templates : le principe DRY appliqué aux vues
L'une des fonctionnalités les plus puissantes de Twig est son système d'héritage de templates. Ce mécanisme permet de définir un squelette de base (ou "layout") pour votre site web, contenant les éléments communs à toutes les pages (ou à un ensemble de pages), comme l'en-tête, le pied de page, la navigation, les inclusions de CSS et JavaScript, etc. Les templates enfants peuvent ensuite "hériter" de ce squelette et ne surcharger que les parties spécifiques qui diffèrent.
Ce concept est une application directe du principe DRY (Don't Repeat Yourself) à vos vues. Au lieu de copier-coller la structure HTML commune dans chaque page, vous la définissez une seule fois dans un template parent. Cela rend votre code de template beaucoup plus facile à maintenir : si vous devez modifier l'en-tête du site, vous ne le faites qu'à un seul endroit (le template parent), et la modification est répercutée sur toutes les pages qui en héritent.
L'héritage dans Twig repose sur deux tags principaux : {% extends '...' %} pour spécifier le template parent, et {% block nom_du_bloc %} ... {% endblock %} pour définir des zones de contenu que les templates enfants peuvent redéfinir.
Définir un template de base (layout) avec des `block`
Un template de base, souvent nommé base.html.twig et placé à la racine du répertoire templates/, définit la structure HTML globale de votre site. A l'intérieur de ce template, vous allez identifier les zones qui seront variables d'une page à l'autre et les marquer avec des tags {% block %}.
Chaque {% block %} a un nom unique. Ce nom servira de référence pour les templates enfants qui voudront surcharger son contenu. Un bloc peut avoir un contenu par défaut, qui sera utilisé si un template enfant n'en fournit pas de nouveau.
Voici un exemple simple de templates/base.html.twig :
{% block title %}Mon Super Site{% endblock %}
{% block stylesheets %}
{# Exemple d'inclusion de CSS avec Webpack Encore #}
{# {{ encore_entry_link_tags('app') }} #}
{% endblock %}
{% block body %}
{% endblock %}
{% block javascripts %}
{# Exemple d'inclusion de JS avec Webpack Encore #}
{# {{ encore_entry_script_tags('app') }} #}
<script src="{{ asset('js/main.js') }}"></script>
{% endblock %}
Dans ce layout, nous avons défini plusieurs blocs :
title: Pour le titre de la page (dans la balise). Il a un contenu par défaut "Mon Super Site".stylesheets: Pour inclure les feuilles de style CSS spécifiques à une page, en plus des styles globaux.body: Le bloc principal où le contenu spécifique de chaque page sera inséré.copyright_year: Pour l'année du copyright, avec l'année actuelle par défaut.javascripts: Pour inclure les fichiers JavaScript spécifiques à une page.
Etendre un template de base avec `extends` et surcharger les `block`
Maintenant que nous avons un template de base, les templates spécifiques à chaque page (par exemple, la page d'accueil, une page de produit, etc.) peuvent en hériter en utilisant le tag {% extends %}. Ce tag doit être la toute première instruction dans le fichier template enfant.
Une fois le template parent étendu, le template enfant peut redéfinir (ou surcharger) le contenu des blocs définis dans le parent. Pour ce faire, il suffit de redéclarer le bloc avec le même nom.
Voici un exemple de template pour une page d'accueil, templates/page/accueil.html.twig, qui hérite de base.html.twig :
{% extends 'base.html.twig' %} {# Doit être la première ligne #}
{# Surcharge du bloc 'title' défini dans base.html.twig #}
{% block title %}Accueil - Bienvenue sur Mon Super Site{% endblock %}
{# Surcharge du bloc 'stylesheets' pour ajouter des styles spécifiques #}
{% block stylesheets %}
{{ parent() }} {# Inclut le contenu original du bloc parent (style.css) #}
<link rel="stylesheet" href="{{ asset('css/accueil.css') }}">
{% endblock %}
{# Surcharge du bloc 'body' pour le contenu principal de la page d'accueil #}
{% block body %}
<div class="jumbotron">
<h1>Bienvenue !</h1>
<p>Découvrez nos incroyables produits et services.</p>
<a href="{{ path('app_produits_list') }}" class="btn btn-primary">Voir les produits</a>
</div>
<section class="dernieres-nouvelles">
<h2>Dernières nouvelles</h2>
<!-- ... contenu des nouvelles ... -->
</section>
{% endblock %}
{# Le bloc 'javascripts' n'est pas surchargé ici, donc il utilisera #}
{# le contenu par défaut de base.html.twig (main.js) #}
{# Le bloc 'copyright_year' n'est pas surchargé non plus, il affichera l'année actuelle #}Points importants à noter :
{% extends 'base.html.twig' %}indique que ce template hérite debase.html.twig.- Chaque
{% block nom_du_bloc %} ... {% endblock %}dans ce fichier remplace le contenu du bloc du même nom dansbase.html.twig. - La fonction
parent(): Dans un bloc surchargé (commestylesheetsici), si vous voulez inclure le contenu original du bloc parent en plus de votre nouveau contenu, vous pouvez appeler{{ parent() }}. C'est très utile pour ajouter des CSS/JS spécifiques à une page sans perdre les CSS/JS globaux. - Si un bloc du parent n'est pas redéfini dans l'enfant (comme
javascriptsoucopyright_yeardans cet exemple), son contenu par défaut (s'il en a un) sera utilisé. Si le bloc parent était vide et n'est pas surchargé, il restera vide.
Héritage multiple et organisation des templates
L'héritage de templates dans Twig peut s'étendre sur plusieurs niveaux (héritage multiple). Par exemple, vous pourriez avoir :
base.html.twig: Layout global du site.blog/layout.html.twig: Un layout spécifique pour la section blog, qui étendbase.html.twiget définit des blocs supplémentaires ou surcharge des blocs debase.html.twig(par exemple, pour ajouter une barre latérale spécifique au blog).blog/post_show.html.twig: Le template pour afficher un article de blog, qui étendblog/layout.html.twiget remplit les blocs de contenu spécifiques à l'article.
Cette capacité à chaîner l'héritage permet une organisation très modulaire et flexible de vos templates. Vous pouvez créer des layouts pour différentes sections de votre site (blog, boutique, panel d'administration) qui héritent tous du layout principal, tout en partageant certains éléments communs et en spécialisant d'autres.
Conseils pour une bonne organisation :
- Nommez vos blocs de manière sémantique : Utilisez des noms clairs et descriptifs pour vos blocs (
main_content,sidebar_right,page_scripts) pour faciliter la compréhension. - Gardez les layouts de base concis : Le
base.html.twigdevrait contenir uniquement la structure la plus fondamentale. Les éléments spécifiques à des sections peuvent aller dans des layouts intermédiaires. - Utilisez des sous-répertoires : Organisez vos templates dans des sous-répertoires dans
templates/pour refléter la structure de votre application (par exemple,templates/product/,templates/security/,templates/admin/). Cela rend les chemins dansextendsetincludeplus clairs.
L'héritage de templates est une pierre angulaire de la construction d'interfaces utilisateur maintenables et évolutives avec Symfony et Twig. Sa maîtrise vous permettra de gagner énormément de temps et de garantir une cohérence visuelle et structurelle à travers l'ensemble de votre application.