Pourquoi une équipe habituée à Twig sur Symfony se sent-elle systématiquement perdue devant un thème WordPress classique ? La réponse tient en un mot : le mélange. Un fichier single.php traditionnel entrelace requêtes à la boucle WordPress, logique conditionnelle et balisage HTML dans le même fichier, alors que l’habitude Symfony sépare strictement le contrôleur du template.
Timber répond précisément à ce besoin en introduisant Twig comme moteur de gabarits pour WordPress, avec un objet Timber\Context qui joue un rôle proche de celui d’un contrôleur Symfony : préparer les données, puis les transmettre à un template qui ne fait plus que les afficher.
Étape 1 : installer Timber via Composer
Timber s’installe comme une dépendance Composer classique du thème, ce qui correspond déjà aux habitudes d’une équipe Symfony :
composer require timber/timber
Le thème doit ensuite charger Timber au démarrage, généralement dans functions.php, en instanciant la classe principale qui active le moteur de rendu Twig pour l’ensemble du thème.
Étape 2 : remplacer la boucle par un contexte

Là où un thème classique construit sa page dans une boucle PHP directement mêlée au HTML, Timber sépare la préparation des données de leur affichage. Le fichier single.php devient un point d’entrée minimal :
<?php
$context = Timber::context();
$context['post'] = Timber::get_post();
Timber::render( 'single.twig', $context );
Le gabarit single.twig, lui, ne contient plus aucune logique PHP visible :
{% extends "base.twig" %}
{% block content %}
<article>
<h1>{{ post.title }}</h1>
{{ post.content }}
</article>
{% endblock %}
Étape 3 : construire des contextes réutilisables
L’intérêt principal pour une équipe Symfony est de retrouver la notion de contexte partagé entre plusieurs templates, proche de ce qu’apportent les extensions Twig globales côté Symfony. Timber permet d’enrichir Timber::context() avec des données communes à tout le site (menu principal, options de thème, informations de pied de page), disponibles automatiquement dans chaque gabarit sans répétition.
- Centraliser la construction du contexte global dans un fichier dédié, chargé une seule fois via un filtre
timber/context. - Créer des gabarits parents (
base.twig) avec des blocs surchargeables, comme on hériterait d’un template Symfony de base. - Déplacer les requêtes complexes vers des classes PHP dédiées plutôt que dans les fichiers de routage du thème, pour garder les points d’entrée légers.
- Utiliser les filtres Twig personnalisés pour reproduire les transformations habituellement faites dans les extensions Twig de Symfony.
Adapter les archives et les templates de blocs
Les fichiers d’archive suivent le même principe : une requête WordPress classique (WP_Query ou la requête principale via Timber::get_posts()) alimente un contexte, transmis à un gabarit Twig qui itère sur la collection avec une syntaxe {% for %} familière à quiconque a déjà écrit du Twig.
Ce que Timber ne change pas
- La hiérarchie de templates WordPress reste identique : Timber ne remplace pas
single.php,archive.phpoupage.php, il change simplement ce que ces fichiers contiennent. - Les hooks et filtres WordPress fonctionnent exactement comme avant, y compris dans un thème basé sur Timber.
- L’éditeur de blocs et les gabarits
theme.jsonrestent indépendants de Timber, qui se concentre sur le rendu côté thème classique.
Twig ne rend pas WordPress plus simple, il rend simplement visible ce qui, dans un thème classique, restait caché dans l’ordre d’exécution du PHP.
En résumé
Pour une équipe qui découvre WordPress après des années de Symfony, Timber comble l’écart de confort le plus immédiat : la séparation entre logique et affichage. Ce choix n’est pas neutre en termes de performance comparée au PHP natif, un sujet qui mérite un article à part, mais il réduit considérablement le temps d’adaptation d’une équipe habituée à raisonner en contrôleurs et en gabarits plutôt qu’en fichiers de template entremêlés.