TP n°5 - Gabarits (templates) Twig pour créer les pages HTML
Ajout de gabarits Twig dans l’application ToDo
Table des matières
- 1. Introduction
- 2. Étape 1 : Mise en place de la séance
- 3. Étape 1 : Ajout de gabarits Twig dans l’application
ToDo
- 4. TODO Étape 2 : Utilisation de la barre d’outils Symfony pour la mise au point
- 5. Étape 3 : Remplacement du code HTML par des gabarits, dans ToDo
- 5.1. TODO Étape 3-a : Consultation d’une collection de tâches
- 5.2. TODO Étape 3-b : Amélioration du rendu de la liste de tâche, sous forme de tableau
- 5.3. TODO Étape 3-c : Utilisation d’un gabarit pour l’affichage d’une instance de tâche
- 5.4. TODO Étape 3-d : Ajout d’un lien de navigation entre liste des tâches et affichage d’une tâche
- 6. Étape 4 : Utilisation de
dump()
pour faciliter la mise au point - 7. TODO Étape 5 : Affichage des tâches terminées
- 8. Conclusion
- 9. TODO Étape 6 : Mise en place des gabarits Twig dans votre projet
- 10. Évaluation
- 11. Pour aller plus loin (optionnel)
1. Introduction
Cette séance va permettre d’expérimenter l’application des
concepts présentés dans le cours qui précède, à travers
la mise en œuvre d’interfaces HTML pour une
application Symfony avec Twig, sur la base de
l’application fil-rouge ToDo
.
Nous nous concentrons sur le moteur de gabarits (templates) Twig, le composant de Symfony permettant la génération des pages Web de l’application. En utilisant Twig, on peut notamment standardiser la structure des pages du site avec un jeu de gabarits permettant d’unifier le contenu de toutes les pages.
Dans cette séance, nous faisons référence à des rudiments d’HTML, en nous appuyant sur le travail effectué en autonomie dans la séquence de travail précédente.
2. Étape 1 : Mise en place de la séance
2.1. TODO Préparation du répertoire de travail
Vous allez dupliquer l’arborescence du projet PHP obtenu à la fin de la séance précédente, pour travailler sur une nouvelle version.
Vous pourrez ainsi faire évoluer le code, et revenir en arrière si besoin, en comparant l’état à la fin de la séance prédente, avec l’état courant.
Effectuez les opérations suivantes pour dupliquer le dossier :
cd "$HOME/CSC4101" cp -r tp-02 tp-05 cd tp-05 cd todo-app
Ensuite, dans ce nouveau projet, on va réinitialiser les rouages du cadriciel Symfony avec Composer :
cd "$HOME/CSC4101/tp-05/todo-app" rm -fr composer.lock symfony.lock var/cache/ vendor/ .project symfony composer install
Confirmez la génération de fichiers pour Docker (on ne s’en servira pas tout de suite, mais pourquoi ne pas les avoir… le rôle de Docker ne sera pas évoqué en cours, mais vous pouvez en parler à vos encadrants de TP).
Cette étape est nécessaire car Symfony s’appuie sur une mécanique
sophistiquée de mise en cache du code de
l’application (dans var/cache/
), pour assurer des performances
maximales. Malheureusement, si on duplique un projet, une partie de ce
cache a tendance à devenir incohérente (présence de chemins d’accès « en dur », etc.).
Il est donc préférable de réinitialiser le projet radicalement : à
un état le plus « propre » possible. On fait ensuite réinstaller par Composer
les bibliothèques du cadriciel Symfony (installées dans vendor/
), et
reconfigurer certains fichiers de configuration associés.
2.2. TODO Chargement du nouveau projet dans l’IDE
Vous allez travailler sur un nouveau projet dans le workspace dans l’IDE Eclipse, importé depuis ce nouveau répertoire de travail.
Pour les utilisateurs de l’IDE Eclipse, supprimez les anciennes infos du projet Eclipse :
cd "$HOME/CSC4101/tp-05/todo-app" rm -fr .project .settings/
Importez dans votre IDE cette nouvelle version du projet Symfony Todo sur laquelle vous allez maintenant travailler.
Dans Eclipse vous pouvez importer ce nouveau projet dans le même workspace que le précédent, mais avec un nom distinctif (par exemple « todo-tp-5 »).
Si besoin, vous pourrez comparer le code des deux projets « todo-tp-5 » et « todo-tp-2 ». Mais pour l’instant, et pour éviter de vous mélanger, nous vous conseillons de fermer le projet de la séance précédente (menu Project / Close …).
3. Étape 1 : Ajout de gabarits Twig dans l’application ToDo
L’objectif de cette étape est d’étudier comment fonctionne la mise en place d’un gabarit standard pour différentes pages d’une même application, et de pratiquer la syntaxe du langage Twig.
Nous allons maintenant travailler sur code de l’application de
gestion de tâches (ToDo
) qui nous sert de fil-rouge, en réalisant la
mise en œuvre de la génération de pages avec des gabarits.
3.1. Principe de la génération du HTML grâce au moteur de rendu des gabarits
En utilisant des gabarits, pour produire du HTML, le code des classes contrôleurs de notre application n’aura plus besoin de manipuler des chaînes de caractères à concaténer.
Il se contente de construire une représentation minimaliste des ressources à afficher dans les pages, puis de demander au moteur de rendu Twig d’en faire un rendu HTML.
Twig va injecter cette représentation dans des gabarits qui contiennent un squelette de HTML, et dans lequel sont prévus des emplacements pour insérer les différents champs de cette représentation minimaliste.
3.2. TODO Modification de l’affichage des tâches
Vous travaillez sur le contrôleur réalisant l’affichage des tâches
TodoController
pour qu’il utilise les gabarits Twig.
Vous allez donc faire en sorte qu’il n’y ait plus de
traces de HTML dans le code PHP de la classe contrôleur. À la place on devra
trouver l’appel à une méthode render()
qui utilise un fichier Twig
et un
tableau associatif avec des variables.
Vous pouvez vous inspirer du code qui avait été généré par make:controller
pour
TagController
, et qui utilise Twig.
Vous pouvez par exemple ajouter un nouveau fichier
index.html.twig
dans le répertoiretemplates/
, qui contient les fichiers gabarit de Twig utilisés par la méthoderender()
:{% extends 'base.html.twig' %} {% block title %}Welcome!{% endblock %} {% block body %} <h1>Welcome</h1> <p>{{ welcome }}</p> {% endblock %} {# body #}
Si la syntaxe des gabarits Twig n’estreconnue immédiatement par Eclipse, vous pouvez installer le plugin Twig pour Eclipse, via le Eclipse Marketplace.
Un plugin Jinja pourrait probablement faire l’affaire également.
Ensuite, vous pouvez modifier la méthode d’affichage de la page d’accueil de l’application pour qu’elle utilise ce gabarit :
// src/Controller/TodoController.php // ... #[Route('/todo')] class TodoController extends AbstractController { #[Route('/', name: 'home', methods: ['GET'])] public function indexAction(): Response { return $this->render('index.html.twig', [ 'welcome' => "Bonne utilisation de la todo list" ] ); }
- Examinez la façon avec laquelle les données sont insérées
pour construire la page affichable (HTML), au travers de l’inclusion
de variables comme
welcome
, qui va être insérée dans la cible{{ welcome }}
. - Modifiez ce message et rechargez la page pour voir l’affichage changer.
On va voir plus loin que Twig ne permet pas seulement d’injecter des valeurs dans des champs à l’intérieur d’un fichier HTML. Il permet aussi d’effectuer des traitements pour factoriser des motifs, ou gérer des traitements conditionnels, par exemple.
3.3. TODO Observation de la structure des pages standardisée
Observez le code source de la page HTML générée par Twig, dans le navigateur Web (Ctrl-U, ou menu bouton droit, puis « Code source de la page »).
Vous y trouvez du code HTML ressemblant à :
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Welcome!</title> <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text></svg>"> </head> <body> <h1>Welcome</h1> <p>Bonne utilisation de la todo list</p> <div id="sfwdtbdd3ea" class="sf-toolbar sf-display-none" role="region" aria-label="Symfony Web Debug Toolbar">...
Ignorez la partie du
<div class="sf-toolbar ...">
en fin de page, qui correspond à l’affichage de la barre d’outils Symfony.Comparez avec le code du gabarit
templates/index.html.twig
ci-dessus.Vous devriez voir la partie utile du HTML provenant du bloc twig
body
({% block body %}...{% endblock %}
).Mais d’où provient le reste du HTML de ce qui précède :
<html>
,<head>
, …</head>
, jusqu’à<body>
?Observez le contenu du fichier source du gabarit
templates/base.html.twig
Vous y voyez justement tous ces éléments du gabarit HTML de base.
Les différents fichiers Twig définissent des blocs, avec les balises Twig
{% block ... %}
et{% endblock %}
. Ici, justement le gabarit de basebase.html.twig
défnii un bloc Twigbody
par défaut, vide :{% block body %}{% endblock %}
(il n’y a rien entre la balise ouvrante « block » et la balise fermante « endblock »).L’instruction
{% extends 'base.html.twig' %}
en en-tête deindex.html.twig
permet de de mettre en place un système de surcharge des blocs de ce gabarit de base, comme autant de motifs permettant de construire une factorisation et une réutilisation pour la structure des pages HTML.Vous devriez comprendre le principe de surcharge des blocs, comme la surcharge de méthodes dans l’orienté objet.
Le rendu du gabarit fonctionne comme un compilateur : il part du gabarit de base (
base.html.twig
), qui est « étendu » (surchargé) par les gabarits spécialisés, commeindex.html.twig
, ici. Si un bloc Twig (commebody
) est surchargé, c’est la version surchargée qui remplace la version de base.C’est donc le contenu fourni entre les balises « block body » et « endblock » de
index.html.twig
qui va s’insérer dans le gabarit de base.- De la même façon, comprenez-vous le rôle du bloc «
title
» , danstemplates/base.html.twig
?
Avec ce mécanisme de surcharge de blocs, on peut définir une structure générale, puis la personnaliser, faire des cas particuliers.
On peut ainsi décliner un gabarit général en spécificités relatives à chacune des sections ou des pages particulières de l’application.
Pour les Web designers, la conception des gabarits consiste donc à chercher des motifs factorisables (généralisables), ou spécialisables, et s’apparente à la conception orientée objet qu’on applique pour la programmation.
4. TODO Étape 2 : Utilisation de la barre d’outils Symfony pour la mise au point
L’objectif de cette étape est de découvrir les fonctionnalités de la barre d’outils de Symfony pour les gabarits.
Comme on l’a déjà vu, pendant le développement de l’application, l’environnement Symfony est
réglé en mode dev
. En conséquence, en bas de chaque page Web générée
par Symfony se trouve une barre d’outils permettant d’accéder à de
nombreux outils facilitant la mise au point.
Testez l’affichage des pages de l’application dans lequelles les gabarits Twig sont maintenant utilisés.
Consultez les informations affichées dans la barre d’outils Symfony en
bas de pages, où vous devriez trouver une nouvelle icône correspondant aux gabarits Twig.
L’outil du Profiler correspondant à la génération des gabarits Twig
donne des informations sur ce qui se passe sous le capot.
Le Rendering Call Graph est particulièrement intéressant en montrant l’enchaînement des générations des différents blocs surchargés.
Pour l’affichage de /todo/
il devrait donner quelque chose du style :
main 11.73ms/100% └ index.html.twig 11.44ms/98% │ └ base.html.twig 10.98ms/94% │ └ index.html.twig::block(title) │ └ base.html.twig::block(stylesheets) 10.94ms/93% │ └ base.html.twig::block(javascripts) │ └ index.html.twig::block(body) └ @WebProfiler/Profiler/toolbar_js.html.twig └ @WebProfiler/Profiler/toolbar.html.twig │ └ @WebProfiler/Profiler/cancel.html.twig::block(toolbar) │ └ @WebProfiler/Profiler/toolbar_item.html.twig └ @WebProfiler/Profiler/toolbar.css.twig
On voit l’enchaînement :
index.html.twig
inclutbase.html.twig
- comme
base.html.twig
contient le rendu de 4 blocs :title
,stylesheet
,javascripts
etbody
, on les voit apparaître successivement. Mais :stylesheet
,javascripts
sont notés comme étant ceux debase.html.twig
. Normal, ils n’ont pas été surchargés.- par contre,
title
etbody
proviennent deindex.html.twig
car ce template les a redéfinis, pour les besoins de cette page particulière de l’application.
- Le reste des gabarits de
@WebProfiler
correspond aux outils du Profiler inclus dans la page.
5. Étape 3 : Remplacement du code HTML par des gabarits, dans ToDo
À l’image de ce qui a été montré ci-desssus pour la page d’accueil,
on va modifier les différentes méthodes du contrôleur TodoController
, pour utiliser les
gabarits, au lieu d’une génération de chaînes de caractère HTML dans
le code PHP.
5.1. TODO Étape 3-a : Consultation d’une collection de tâches
Procédez aux opérations suivantes :
Créez un sous-répertoire
templates/todo/
et à l’intérieur, un nouveau gabaritindex.html.twig
, contenant :{% extends 'base.html.twig' %} {% block title %}Welcome!{% endblock %} {% block body %} <h1>Todo index</h1> <ul> {% for todo in todos %} <li>{{ todo.title }}</li> {% endfor %} {# todos #} </ul> {% endblock %} {# body #}
Notez qu’on utilise
{{ }}
pour afficher la valeur d’une variable, alors qu’on utilise{% %}
pour exécuter des instructions Twig.
Modifiez le code de la méthode du contrôleur
TodoController
pour utiliser ce gabarit :/** * Lists all todo entities. */ #[Route('/list', name: 'todo_list', methods: ['GET'])] #[Route('/index', name: 'todo_index', methods: ['GET'])] public function listAction(ManagerRegistry $doctrine): Response { $entityManager= $doctrine->getManager(); $todos = $entityManager->getRepository(Todo::class)->findAll(); // dump($todos); return $this->render('todo/index.html.twig', [ 'todos' => $todos ] ); }
Le contrôleur passe en argument au rendu Twig la variable
todos
, qui contient une collection d’entités Doctrine (vérifiez en dé-commentant l’appel àdump()
).Notez la différence par rapport à la version précédente, qui faisait un
foreach($todos as $todo)
dans le code PHP. Ccette fois, c’est dans le gabarit Twig que se produit l’algorithme d’itération foreach sur l’affichage de chaque élément d’une collection, avec l’instruction{%for ITEM in COLLECTION %}
.Twig peut alors accéder « nativement » aux propriétés des instances de classes PHP présentes dans la collection :
{{ todo.title }}
se traduira en un appel àTodo:getTitle()
.- Testez l’affichage de la page
/todo/list
, donc le code source HTML doit bien contenir les éléments du gabarit de base Modifiez
<li>{{ todo.title }}</li>
danstemplates/todo/index.html.twig
.Vous pouvez par exemple afficher
<li>Title: {{ todo.title }}</li>
, ou ajouter l’identifiant des taches :<li>({{ todo.id }}) {{ todo.title }}</li>
.Vérifiez que le simple rechargement de la page dans le navigateur permet de voir le résultat.
Il n’y a plus forcément besoin de modifier le code PHP. On peut se séparer le travail entre adaptations du code PHP et du contenu des pages dans Twig. Modularisation souhaitable pour améliorer la qualité.
Pour vérifier qui fait quoi, essayez de modifier le code de
Todo::getTitle()
pour ajouter, par exemple un caractère « ! » au début du titre de chaque tâche :public function getTitle(): ?string { return '!' . $this->title; }
Rechargez la page Web : la modification est appliquée… mais alors elle s’applique aussi à
symfony console app:list-todos
…
On voit bien sur cet exemple que les gabarits Twig qui construisent les vues de notre application, sont câblés correctement par Symfony avec les données du modèle objet de Doctrine.
En cas de changement, il convient de se mettre d’accord : est-ce qu’une modification de l’application doit porter sur le modèle de données ou sur la présentation Web (ou les deux). On sait ainsi où intervenir : PHP, ou Twig.
5.2. TODO Étape 3-b : Amélioration du rendu de la liste de tâche, sous forme de tableau
On va modifier encore le gabarit templates/todo/index.html.twig
pour
afficher toutes les propriétés des tâches dans un tableau.
Au lieu d’une liste à puces simple, on veut obtenir un tableau HTML du type :
<table class="table"> <thead> <tr> <th>Id</th> <th>Todo</th> <th>Completed</th> <th>Created</th> <th>Updated</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>apprendre les bases de PHP</td> <td>1</td> <td>2018-08-06 14:03:57</td> <td>2018-08-06 14:03:57</td> </tr> ... </tbody> </table>
Modifiez le code du gabarit templates/todo/index.html.twig
autour du foreach, pour afficher ainsi les
différentes propriétés de chaque tâche présente dans todos
.
Notez que les dates peuvent être affichées avec une instruction Twig
d’affichage d’une variable, du type : {{ todo.created ? todo.created|date('Y-m-d H:i:s') : '' }}
, qui signifie :
- si l’attribut
created
est défini (on utilise la contruction de l’opérateur ternaire « ? : », plutôt qu’un if/then/else), alors on va afficher sa valeur sous forme de date avec un certain format d’affichage (on utilise un « filtre » d’affichage de valeur avec l’opérateur{{ ... | FORMAT }}
- cf. https://twig.symfony.com/doc/3.x/filters/date.html) - sinon, afficher une chaîne vide
On ne vous fournit pas le squelette à copier/coller, cette fois. Il faut un peu démarrer la réflexion sur le code. Ce n’est pas très complexe, mais prenez le temps de relire attentivement les instructions.
5.3. TODO Étape 3-c : Utilisation d’un gabarit pour l’affichage d’une instance de tâche
L’objectif de cette étape est de mieux comprendre le fonctionnement de la
surcharge des blocs dans les gabarits Twig, et d’introduire path()
.
Soyez attentifs, cette étape est un peu moins triviale… méfiez-vous du copier/coller.
L’affichage d’une tâche d’identifiant 1 est réalisée sur le chemin http://localhost:8000/todo/1.
Modifiez maintenant l’affichage d’une seule tâche, en vous inspirant des extraits suivants :
adaptez la méthode du contrôleur qui va gère les requêtes HTTP entrantes, qui devrait ressembler à ceci :
/** * Finds and displays a todo entity. */ #[Route('/{id}', name: 'todo_show', requirements: ['id' => '\d+'], methods: ['GET'])] public function showAction(Todo $todo): Response { return $this->render('todo/show.html.twig', [ 'todo' => $todo ] ); }
Pour l’instant on laisse un peu de côté l’explication de la « magie » qui permet de récupérer l’instance de
Todo
grâce à doctrine, dans ce code (cf. « Aller plus loin » optionnel).ajoutez un nouveau gabarit
templates/todo/show.html.twig
(en recopiant son « cousin »todo/index.html.twig
, par exemple), contenant par exemple la génération d’un tableau HTML du type :{# ... #} {% block body %} <h1>Todo show</h1> {% dump todo %} <table class="table"> <tbody> <tr> <th>Id</th> <td>{{ todo.id }}</td> </tr> <tr> <th>Title</th> <td>{{ todo.title }}</td> </tr> ... </tbody> </table> <a href="{{ path('todo_index') }}">back to list</a> {% endblock %} {# body #} {# ... #}
Le lien « back to list » en bas de page contient une balise HTML de lien
<a href="">...</a>
tout à fait classique pour accéder à une autre page de l’application.La valeur de son attribut
href
(l’URL cible du lien), est définie à{{ path('todo_index') }}
. C’est la même construction{{ ... }}
Twig pour afficher la valeur d’une variable. Elle va juste faire appel à une fonction de Symfony pour Twig :path( )
.La fonction
path( )
prend en premier argument le nom d’une route de Symfony (icitodo_index
), et renvoie le chemin de cette route qui sera la cible du lien (ici ce sera/todo/index
). Ce sont les noms et chemins définis par le Routeur de Symfony vus plus haut.Vérifiez que l’affichage fonctionne bien, et que le lien est naviguable, en corrigeant le nom de la route si nécessaire.
Est-ce que l’affichage fonctionne bien ? Est-ce que la barre d’outils Symfony est toujours affichée ?
Si elle ne s’affiche pas, utilisez les outils du développeur Web dans le navigateur pour voir si quelque chose n’est pas cassé :
- Consultez le code source de la page, et vérifiez qu’elle contient bien du HTML bien formé… avec tout ce qui va bien….
- Y a-t-il les éléments nécessaire à l’affichage de la barre d’outils Symfony dans la page ?
Indice pour réparer l’affichage : il est nécessaire de bien remettre en place cette
génération d’HTML complète, en faisant comme dans le gabarit
todo/index.html.twig
: il faut bien l’inclusion du gabarit de base : {% extends
'base.html.twig' %}
au début du gabarit, même si nous ne l’avons pas
inclus dans le code à copier/coller, ci-dessus. Méfiez-vous des {#
... #}
!
Une fois que c’est fait, la barre d’outils Symfony doit se rafficher correctement.
Bravo : vous avez compris comment fonctionne la surcharge des gabarits. Vous savez maintenant comment factoriser des blocs de contenu des pages, et les spécialiser dans certaines pages d’une application.
5.4. TODO Étape 3-d : Ajout d’un lien de navigation entre liste des tâches et affichage d’une tâche
L’objectif de cette étape est de mieux comprendre l’utilité de la fonction path()
.
On va ajouter dans la consultation de la collection
des tâches (/todo/list
), un lien pointant vers la page de consultation de chacune
de ses tâches.
Ajoutez dans le tableau des tâches (todo/index.html.twig
), une dernière colonne pour contenir des liens navigables :
<thead> <tr> ... <th> </th> </tr> </thead> <tbody> ... <tr> ... <td><a href="{{ path('todo_show', {'id': todo.id}) }}">show</a></td> </tr> </tbody>
Dans ces balises HTML de lien, l’attribut href
doit pointer vers l’URL d’affichage
correspondant à la tâche courante. Cette URL varie, pour chaque tâche
à afficher, puisqu’elle contient l’identifiant de la tâche.
Cette fois encore, la fonction path( )
doit prendre en premier
argument le nom de la route. Mais elle doit aussi recevoir la valeur des arguments de
cette route, qui rendent l’URL dynamique.
Ici, la route todo_show
attend un argument ’id
’, comme cela est défini
dans l’attribut de l’annotation #Route('/{id}'
de
TodoController::showAction()
.
On passe les arguments qu’elle attend via un tableau associatif en
syntaxe Twig (façon dictionnaire Python) : id
vaut todo.id
. Voilà pour {{ path('todo_show', {'id': todo.id}) }}
.
Votre interface est navigable dans les deux sens : de la collection (index) aux entités (show), et retour.
Bravo : vous connaissez presque tous les éléments fondamentaux pour programmer une interface Web en consultation avec Twig.
6. Étape 4 : Utilisation de dump()
pour faciliter la mise au point
En cours de développement, pour faciliter le débogage (debug), nous
avons vu que vous pouvez introduire l’affichage d’un objet
en utilisant la fonction dump()
dans le code PHP, par exemple à l’intérieur d’une méthode d’action contrôleur, avant l’appel
à la méthode render
:
$todos = $em->getRepository(Todo::class)->findAll(); dump($todos);
Mais vous pouvez aussi utiliser la fonction dump()
à l’intérieur d’un
gabarit Twig, dans une instruction dump de Twig, appelée avec :
{% dump todo %}
Dans les deux cas, la présence des informations de debug
correspondantes aux appels à dump()
se retrouve dans la console
Symfony, derrière l’icône en forme de « cible » qui apparaît alors dans la barre d’outils du développeur Symfony.
Attention : {% dump todo %}
est différent de {{ dump(todo) }}
: la
première est une instruction Twig (précédée de « {%
», comme un for)
, alors que la seconde
affiche la valeur des informations de debug (une chaîne de caractère
contenant du code HTML, tel que renvoyé par l’appel à dump(todo)
)
inséré au milieu du rendu de la
page (comme pour tout accès à une variable via « {{ ... }}
»). La
deuxième pollue l’affichage, quand la première cache juste les infos
de debug derrière la « cible » de la barre d’outils Symfony.
7. TODO Étape 5 : Affichage des tâches terminées
L’objectif de cette étape est de mettre en forme les tâches terminées de façon différente des tâches à faire, grâce aux instructions Twig dans les gabarits.
On souhaite par exemple afficher les tâches terminées comme étant barrées, dans la liste des tâches.
C’est l’étape finale qui est le moins guidée. Bon courage.
Vous pouvez utiliser la balise HTML <del>
pour ce faire.
Vous exploiterez la primitive if
du langage de gabarits de Twig, en vous référant à la documentation de référence de Twig.
Modifiez le gabarit d’affichage de la liste des tâches (index.html.twig
) pour intégrer ce changement
Dans les données d’exemple de l’application fournies, seule la tâche
« terminer le hp 2-3 » « apprendre les bases de PHP »
a le statut terminé ;-).
8. Conclusion
Comme vous l’aurez maintenant compris, dans une application Symfony, une partie des algorithmes peuvent être programmés dans le code PHP. C’est particulièrement vrai pour ce qui concerne le modèle de données, avec Doctrine. On peut par exemple changer l’ordre de chargement des données, comme on l’a vu dans une séance précédente, au niveau de la surcharge de la méthode findAll() dans le Repository.
Mais on peut aussi programmer certains comportements dans les gabarits Twig, avec sa syntaxe propre, par exemple pour faire varier seulement la présentation des données.
Il faudra faire un choix : appliquer des traitements dans les couches modèle et traitements en PHP, ou dans la couche présentation en TWig… tout dépend des compétences des différents développeurs (PHP vs Twig ?), mais aussi des contraintes : performances, encombrement mémoire, factorisation. À vous de décider.
9. TODO Étape 6 : Mise en place des gabarits Twig dans votre projet
Vous pouvez maintenant mettre en pratique ce que nous venons de voir, sur les gabarits Twig, dans votre projet.
Le principe est de structurer des pages Web avec des gabarits, plutôt que de faire du HTML « à la main ».
Poursuivez la séance en déroulant les étapes du guide de réalisation du projet.
Vous la continuerez en travail hors présentiel sur votre projet, d’ici la prochaine séance de TP (Notez le label « Après_TP_5 » dans la section du guide de réalisation).
10. Évaluation
À l’issue de cette séance, vous savez :
- construire des pages d’une application à partir de gabarits (templates) Twig
- vous comprenez le principe de surcharge de gabarits pour rendre la structure des pages uniforme
- vous savez utiliser des primitives du langage Twig telles que
if
oufor
- vous savez tisser des liens vers d’autres pages avec
path()
- vous savez examiner des éléments de diagnostic (pour déverminage / debug)
avec
dump()
11. Pour aller plus loin (optionnel)
11.1. Chargement « automagique » d’une instance en consultation grâce à l’Entity Value Resolver
Observez le code de TodoController::showAction()
.
Comprenez-vous comment est obtenue l’instance de Todo
, $todo
qui
est récupérée en paramètre par cette méthode ?
Vous avez bien vu que l’identifiant id
est spécifié dans
l’annotation définissant la route (on précise même que c’est un
entier), qui correspond à l’attribut todo.id
dans la génération des
liens avec path()
dans le gabarit de liste des tâches.
Peut-on instancier en mémoire un objet $todo
chargé depuis la base
de données, une fois qu’on connaît son identifiant ?
On peut utiliser le code suivant, qui utilise explicitement Doctrine, comme dans le TP précédent :
$todo = $em->getRepository(Todo::class)->find($id);
Mais comme une application Symfony finit typiquement par contenir ce genre de code presque systématiquement, les développeurs du framework ont intégré ce mécanisme dans la classe Contrôleur via le mécanisme Entity Value Resolver, de façon a rendre cela « automagique ».
Ce mécanisme, sur lequel reviendra plus tard, instancie automatiquement une classe de notre modèle de données Doctrine, chargée depuis la base de données à partir d’une valeur d’identifiant fournie, lorsqu’il n’y a pas d’ambiguïté.
La documentation Symfony vous donnera plus d’infos, à partir de Automatically Fetching Objects (EntityValueResolver).