Skip to Content

Terrain 7 — Twig & composants

🔍 Renfort : 7.1, 7.2. ⚠️ Toute la syntaxe Twig est dans des blocs de code (les accolades Twig hors code casseraient la page).

1. Afficher une date ⭐

🕹️ Mission : affichez booking.start au format « 09/07/2026 14:30 ».

✅ Solution

{{ booking.start|date('d/m/Y H:i') }}

2. Valeur de repli ⭐

🕹️ Mission : affichez une description ou « — » si vide.

✅ Solution

{{ description|default('—') }}

3. Boucle avec état vide ⭐⭐

🕹️ Mission : listez les services d’un prestataire, avec « Aucun service » si vide.

✅ Solution

{% for service in provider.services %} <li>{{ service.name }}</li> {% else %} <li>Aucun service.</li> {% endfor %}

4. Générer une URL ⭐⭐

🕹️ Mission : un lien vers booking_show sans URL en dur.

✅ Solution

<a href="{{ path('booking_show', { id: booking.id }) }}">Voir</a>

5. Héritage ⭐⭐

🕹️ Mission : une page qui étend base.html.twig et remplit title + body.

✅ Solution

{% extends 'base.html.twig' %} {% block title %}Réservations — {{ parent() }}{% endblock %} {% block body %}<h1>Réservations</h1>{% endblock %}

6. Danger |raw ⭐⭐⭐

🕹️ Mission : pourquoi {{ comment.body|raw }} sur un commentaire utilisateur est-il dangereux ? Que faire ?

✅ Solution

|raw désactive l’échappement → XSS si l’utilisateur injecte du <script>. Laisser Twig échapper (juste {{ comment.body }}), ou assainir avec HtmlSanitizer avant d’afficher.

7. Messages flash ⭐⭐

🕹️ Mission : affichez tous les messages flash.

✅ Solution

{% for label, messages in app.flashes %} {% for message in messages %} <div class="flash flash-{{ label }}">{{ message }}</div> {% endfor %} {% endfor %}

8. Composant Twig ⭐⭐⭐

🕹️ Mission : un composant StatusBadge (classe + template) affichant un badge coloré.

✅ Solution

#[AsTwigComponent] final class StatusBadge { public BookingStatus $status; public function cssClass(): string { return 'badge badge-' . $this->status->value; } }
{# templates/components/StatusBadge.html.twig #} <span class="{{ this.cssClass }}">{{ status.label }}</span> {# usage : <twig:StatusBadge :status="booking.status" /> #}

9. Éviter le N+1 en Twig ⭐⭐⭐⭐

🕹️ Mission : une liste appelle service.provider.name par ligne (N+1). Où corriger ?

✅ Solution

Pas en Twig, mais dans le repository : charger la relation en fetch join (->addSelect('p')->join('s.provider', 'p')) avant de passer les données au template.

10. Include isolé ⭐⭐

🕹️ Mission : incluez une ligne de tableau en ne passant qu’une variable, contexte isolé.

✅ Solution

{% include 'partials/_row.html.twig' with { booking: b } only %}

Terrain suivant : Symfony UX.