Aller au contenu principal

Templates (Vues) - Twig - Introduction

Dans la version webapp, pour faire une application complète, Symfony fournit Twig comme moteur de templates.

Syntaxe​

Les 3 éléments de syntaxe Twig à retenir sont les suivants :

  • Structure de contrôle ou de langage Twig : {% %}
  • Evaluer une expression et afficher le résultat à l'écran : {{ }}
  • Inscrire un commentaire dans un template : {# #}

Exemple​

Exemple d'un fichier Twig :

{# base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>{% block title %}Mon super titre{% endblock %}</title>
{% block stylesheets %}{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>

Dans tout fichier de template, on pourra inclure des instructions Twig pour la compilation du template.

Dans ce premier extrait par exemple, on construit un squelette HTML de base.

Le but est d'avoir un template de base commun pour toutes les pages de notre application.

Les blocs​

On peut donc définir différents blocs dans notre squelette de base, que nous allons mettre à disposition des templates enfants pour qu'ils définissent chacun leur propre contenu :

{# index/index.html.twig #}
{% extends 'base.html.twig' %}

{% block title %}
{# Il est possible de rappeler le contenu du bloc parent avec la fonction parent() #}
{{ parent() }} - Hello TestController!
{% endblock %}

{% block body %}

<div class="example-wrapper">
{# On peut afficher la valeur de variables passées par le contrôleur à la vue #}
<h1>Hello {{ controller_name }}! ✅</h1>
</div>
{% endblock %}
Héritage

Les différents blocs définis dans le template parent vont donc prendre le contenu défini dans le template enfant. On pourra donc définir les contenus de chaque page séparément, en gardant une base d'affichage commune (inclusion des CSS et JS de Bootstrap, etc...)

Les fonctions​

La liste des fonctions disponibles se trouve ici. On n'en cite ici que quelques-unes :

block​

L'élément block utilisé ci-dessus est en fait une fonction. Twig embarque de nombreuses fonctions qui vont nous donner des possibilités supplémentaires, un peu comme avec la SPL :

parent​

C'est aussi présent dans le template ci-dessus : la fonction parent rappelle le contenu du bloc parent afin d'éviter que l'enfant n'écrase systématiquement le contenu d'un bloc hérité.

include​

À la manière de include ou require dans la SPL, on va pouvoir utiliser la fonction include avec Twig pour inclure un template dans un autre. On peut même lui transmettre de la donnée au travers d'un second argument, si le template en question utilise des variables :

{# Template seul #}
{{ include('template.html') }}

{# Template auquel on transmet des données #}
{{ include('template.html', { foo: 'bar' }) }}

Par défaut, le template inclus a accès aux variables définies dans le template qui l'inclut. Il est possible de désactiver cet accès avec un troisième argument booléen with_context.

Structures de contrôle​

Il est possible d'utiliser des structures if ... else dans Twig, ainsi que des boucles for ... in ....

Pour résumer, on pourra se reporter à cette page de la documentation pour avoir une idée de l'utilisation de Twig et ses capacités. On en utilisera et/ou expliquera quelques-unes tout au long du module.

Les extensions Twig fournies par Symfony​

Twig est un moteur de template extensible, ce qui signifie que n'importe qui peut définir ses propres fonctionnalités, en-dehors des fonctions incluses dans le moteur.

Ainsi, dans une application Symfony incluant le TwigBundle, se trouvera le package symfony/twig-bridge. Dans ce package sont définies des extensions Twig.

Générer un lien avec path​

Par exemple, la fonction path permet de générer un lien hypertexte vers une route de l'application.

De base, Twig n'est pas censé connaître Symfony. C'est Symfony qui apporte un ensemble d'extensions, dont la fonction path qui va être couplée au composant Routing de Symfony.

Traditionnellement, si on voulait afficher un lien dans notre application, on pourrait le faire très simplement. Vers une page "À propos", par exemple :

<a href="/about">À propos</a>

Mais le problème qui peut alors se poser est la validité du lien : pensera-t-on à changer le lien vers /about le jour où nous aurons changé l'URL du contrôleur dans l'attribut Route associé ?

Par exemple, dans un contrôleur :

- #[Route('/about', name: 'about')]
+ #[Route('/about-us', name: 'about')]

Il faut alors penser à changer tous les liens vers /about en /about-us dans notre application.

Pour éviter ça, on pourrait plutôt se référer à la route définie dans notre application. On pourrait alors demander au routeur de Symfony (composant Routing) de nous fournir l'URL associée à la route nommée about.

Liste des routes

Depuis le terminal, on peut demander à la console d'afficher toutes les routes enregistrées dans l'application :

php bin/console debug:router

C'est le rôle de la fonction path : on peut l'appeler en lui fournissant le nom d'une route, et elle communiquera avec le routeur (via un générateur d'URL issu du composant Routing) pour aller chercher l'URL correspondante.

Ainsi, dans un template Twig, on peut générer des liens vers des pages en utilisant leur nom :

<!-- La valeur l'attribut href sera transformée en "/about-us" après la mise à jour, pas besoin de retoucher cette balise -->
<a href="{{ path('about') }}">À propos</a>

Il existe de nombreuses extensions Twig définies par Symfony pour nous aider à écrire des templates.