Composer avec des macros plutôt que dupliquer des blocs
Passé le stade des {% for %} et {% if %}, la première brique à maîtriser pour un code de templates propre est la macro. Une macro se comporte comme une fonction : elle prend des paramètres, peut avoir des valeurs par défaut, et s'importe dans un autre fichier.
{# _macros.html.twig #}
{% macro input(name, value = '', type = 'text') %}
<input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
{% endmacro %}
{# formulaire.html.twig #}
{% import '_macros.html.twig' as forms %}
{{ forms.input('email', user.email, 'email') }}
Contrairement à un {% include %}, la macro ne partage pas le contexte global : elle ne voit que ce qu'on lui passe explicitement. C'est un gain de lisibilité, surtout dans les projets où plusieurs développeurs touchent aux mêmes vues.
Filtres et fonctions personnalisés
Créer un filtre maison évite de polluer les contrôleurs avec de la mise en forme. Dans une extension Twig 3.x :
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class TexteExtension extends AbstractExtension
{
public function getFilters(): array
{
return [
new TwigFilter('slugifie', fn(string $s) => strtolower(
preg_replace('/[^a-z0-9]+/i', '-', $s)
)),
];
}
}
Depuis Twig 2.10, les arrow functions sont utilisables directement dans les templates avec filter, map ou reduce : {{ produits|filter(p => p.stock > 0)|map(p => p.nom)|join(', ') }}. Cela remplace avantageusement des boucles verbeuses pour des transformations simples.
Sandbox : exécuter du template non fiable
Si des templates sont générés ou modifiés par des utilisateurs (CMS, éditeur de mise en page), l'extension Sandbox restreint les tags, filtres et méthodes autorisés :
$policy = new SecurityPolicy(
allowedTags: ['if', 'for'],
allowedFilters: ['upper', 'escape'],
allowedMethods: [],
allowedProperties: [],
allowedFunctions: []
);
$twig->addExtension(new SandboxExtension($policy, true));
Sans cette isolation, un utilisateur pourrait appeler n'importe quelle méthode PHP exposée via un objet du contexte.
Performance : cache compilé et strict_variables
Twig compile chaque template en classe PHP native ; le cache disque (cache => '/var/cache/twig') évite de recompiler à chaque requête et doit toujours être activé en production. En développement, garder strict_variables: true force Twig à lever une erreur sur une variable inexistante plutôt que de l'afficher silencieusement comme vide, ce qui évite bien des bugs de template passés inaperçus jusqu'en production.
Enfin, l'autoescaping est actif par défaut sur le contexte HTML : n'utilisez |raw qu'après vous être assuré que la donnée ne peut pas contenir de HTML injecté par un utilisateur.