Faciliter le débogage des templates twig

Lorsque l'on développe un projet sous symfony, il arrive fréquemment que l'on décide de découper ses vues en plusieurs morceaux. Le temps passant, le projet fait appel à une multitude de templates, de sous-templates.... Pour vous, le vieux dev qui est là depuis le départ du projet, il est facile de s'y retrouver et vous allez droit au but. Mais qu'en est il d'un nouveau développeur qui débarque et à qui vous demandez de déboguer une page ?
Il existe pourtant une façon assez simple d'aiguiller vos collègues au sein de votre application et de leur permettre de trouver aisément le template dont est issu un élément inspecté.

La documentation est assez pauvre en la matière, mais heureusement pour nous, on est en 2024 et chatGpt existe. Je dois dire qu'il m'a bien aidé à finaliser cette solution.

Le but

Ajouter, en mode dev, des commentaires html qui renseignent le nom des templates responsables du code inspecté.

Les étapes

La première étape consiste à créer une classe qui va se charger d'exécuter le code nécessaire. Celle ci doit implémenter NodeVisitorInterface.
Il faudra ensuite créer un extension twig qui utilise ce code. Puis déclarer notre extension

Le NodeVisitor

<?php

namespace App\Twig\Listener;

use Twig\Environment;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\TextNode;
use Twig\NodeVisitor\NodeVisitorInterface;

class HtmlCommentNodeVisitor implements NodeVisitorInterface
{

    public function enterNode(Node $node, Environment $env): Node
    {
        if ($node instanceof ModuleNode && $env->isDebug()) {

            $startComment = new TextNode(
                '<!-- ' . $node->getTemplateName() . ' -->',
                $node->getTemplateLine()
            );

            $endComment = new TextNode(
                '<!-- end template -->',
                $node->getTemplateLine()
            );

            $node->setNode('display_start', $startComment);
            $node->setNode('display_end', $endComment);
        }

        return $node;
    }

    public function leaveNode(Node $node, Environment $env): ?Node
    {
        return $node;
    }

    public function getPriority(): int
    {
        return 0;
    }
}

Tel quel, le code a un impact sur la barre de debug de symfony.

if ($node instanceof ModuleNode && $env->isDebug()) {

Evidemment, le $env->isDebug() permet d'exclure ce helper d'un environnement de prod. Mais, même en dev, Il peut être utile d'exclure la barre de debug de symfony de votre Visitor en ajoutant à cette condition :

... && !str_contains($node->getTemplateName(), '@WebProfiler') 

L'extension

<?php

namespace App\Twig\Listener;

use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Twig\Extension\AbstractExtension;

class HtmlCommentExtension extends AbstractExtension
{
    public function getNodeVisitors(): array
    {
        return [new HtmlCommentNodeVisitor()];
    }

}

Déclarer l'extension

Il ne vous reste qu'à déclarer votre extension dans votre config/sevices.yaml

services:
    App\Twig\Listener\HtmlCommentExtension:
        tags: [ 'twig.extension' ]

Et enfin

Lorsque vous inspectez un élément html de votre application, le nom du template n'est désormais jamais loin...