Développer des extensions Twig personnalisées dans Symfony
Vendredi 01 Septembre 2023 08:30

Développer des extensions Twig personnalisées dans Symfony

Que se soit pour gérer facilement un affichage ou réaliser un calcul récurrent, il est intéressant de se faciliter la vie en permettant de réaliser cette opération directement depuis votre template twig et mieux encore, de le rendre générique et réutilisable..

C’est là qu'interviennent les extensions twig.

Une extension twig ?

En réalité on en utilise régulièrement comme par exemple:

{{ 'now'|date('Y') }}

Il s’agit ici d’une extension permettant d’appliquer un filtre sur une date.
Mais si vous êtes déjà utilisateur de Twig, je ne vous apprends rien.

Comment ajouter nos propres extensions ?

Ce n’est pas un secret et vous le trouverez une nouvelle fois dans la doc, mais je vais vous résumer ça en passant directement par la bonne pratique car il y a deux méthodes.

La première consiste à n’utiliser qu’un seul fichier, ce qui ne pose aucun problème.
Du moins en général car il faut savoir que Twig doit initialiser toutes les extensions avant d'effectuer le moindre rendu même si il n’en à pas besoin. Ce qui peut avoir un impact niveau performance.

La deuxième que je vais vous présenter, consiste à utiliser un second fichier qui contiendra nos fonctions qui cette fois ne seront appelées que lors de leur utilisation.

Créons nos fichiers

Nous allons donc créer un fichier “src/Twig/AppExtension.php” qui étend “AbstractExtension”.

namespace App\Twig;

use App\Twig\AppRuntime;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;

class AppExtension extends AbstractExtension
{
    public function getFilters(): array
    {
        return [
            new TwigFilter('helloworld', [AppRuntime::class, 'helloworld']),
        ];
    }
}

Si vous n’avez pas bêtement copié/collé ce code, vous aurez remarqué qu’il fait référence à AppRuntime. Nous allons donc créer ce fichier. C’est ce dernier qui contiendra réellement notre code avec les dépendances nécessaires sans que celà ne puisse impacter les performances.

Toujours au même endroit, on crée dont le fichier “src/Twig/AppRuntime.php”

namespace App\Twig;

use Twig\Extension\RuntimeExtensionInterface;

class AppRuntime implements RuntimeExtensionInterface
{
    public function __construct()
    {}

    public function helloworld(string $name): string
    {
        return 'Hello '.$name.'!';
    }
}

Et c’est tout!

Lors du rendu, Twig va récupérer la liste de vos fonctions via le “getFilters()” du fichier AppExtension et ira rechercher la fonction passée en paramètre dans le fichier AppRuntime lorsque nécessaire.

Et ça s'utilise comment?

Hé bien dans vos templates, vous pouvez désormais utiliser le filtre twig que vous avez créé de cette façon:

{{ 'Kevin'|helloworld }}

Ce qui au rendu donnera

Filtre ou Fonction ?

Jusqu'à présent je vous ai parlé des filtres qui agisse sur une valeur précise

{{ valeur|monFiltre }}

Mais il existe aussi les fonctions qui s’utilise d’une manière plus classique

{{ maFonction(parametreA, parametreB) }}

Vous pouvez donc adapter votre AppExtension en ajoutant ceci

public function getFunctions(): array
{
    return [
        new TwigFunction('helloworld', [AppRuntime::class, 'helloworld']),
    ];
}

Dans cet exemple, j’utilise le même code, il est simplement appelé différemment mais le rendu sera identique

Le résumé

Pour ceux qui voudrait un résumé des fichiers, je vous propose de jeter un oeil au commit fait sur mon projet sandbox concernant ce post !