Le WordPress d'aujourd'hui, décodé pour les développeurs

Headless & API

Timber et Twig préparent une bascule progressive vers le headless

Arborescence commentée d'un thème Timber pensé pour exposer ses données en HTML classique et via l'API REST, en vue d'une transition douce vers un front découplé.

Par WordPress Développement • 26 octobre 2022 • 5 min de lecture • Aucun commentaire
Timber et Twig préparent une bascule progressive vers le headless

Un thème WordPress classique mélange presque toujours trois choses au même endroit : la requête à la base de données, la mise en forme HTML et la logique d’affichage conditionnelle. C’est ce mélange qui rend une migration headless brutale, parce qu’il faut tout réécrire d’un coup pour obtenir un front propre. L’équipe produit d’un éditeur de logiciels de gestion des stocks nous a demandé l’inverse : garder le thème existant qui tournait bien, mais préparer le terrain pour qu’une partie du site bascule progressivement vers une application React sans tout casser.

La réponse a été Timber, la librairie qui sépare la logique PHP des templates via le moteur Twig. Non pas parce que Timber est un framework headless — il ne l’est pas — mais parce que sa structure impose déjà une discipline utile : les données transitent par des objets PHP propres avant d’arriver au template, ce qui les rend tout aussi faciles à sérialiser en JSON qu’à afficher en HTML.

L’arborescence retenue

Voici comment le thème a été réorganisé, avec un dossier models qui n’existe pas dans un thème Timber standard mais que nous avons ajouté pour centraliser la préparation des données :

theme-timber/
├── models/
│   ├── class-produit.php        (étend Timber\Post)
│   ├── class-categorie.php      (étend Timber\Term)
│   └── class-fiche-technique.php
├── views/
│   ├── produit.twig
│   ├── categorie.twig
│   └── partials/
│       ├── fiche-technique.twig
│       └── badge-stock.twig
├── rest/
│   └── class-produit-rest-field.php
├── functions.php
└── style.css

Chaque classe du dossier models hérite d’une classe Timber (Timber\Post le plus souvent) et ajoute des méthodes métier : get_niveau_stock(), get_fiches_liees(), get_badge_couleur(). Le template Twig appelle ces méthodes directement, sans jamais toucher à $wpdb ou à une fonction WordPress brute. C’est ce niveau d’abstraction qui rend la donnée réutilisable ailleurs.

Le miroir REST, vue par vue

Plutôt que de construire un schéma d’API complet dès le départ, nous avons choisi de convertir une vue à la fois. La fiche produit a été la première, parce que c’était celle que l’équipe voulait tester dans un prototype React avant de s’engager plus loin.

L'essentiel à retenir : Les objets Timber deviennent la source unique pour le rendu et l'API ; Chaque vue Twig a un miroir JSON exposé par register_rest_field ; La bascule se fait vue par vue, sans big bang

Le principe : la classe Produit expose déjà une méthode to_array_public() qui retourne exactement les champs jugés sûrs à publier. Le template Twig et le champ REST appellent tous les deux cette même méthode, ce qui élimine tout risque de divergence entre ce que voit un visiteur du site classique et ce que reçoit le futur front React.

class Produit extends Timber\Post {

    public function to_array_public() {
        return array(
            'nom'          => $this->title(),
            'reference'    => $this->meta( 'reference_interne' ),
            'stock'        => $this->get_niveau_stock(),
            'categories'   => wp_list_pluck( $this->terms( 'categorie_produit' ), 'name' ),
        );
    }
}

add_action( 'rest_api_init', function () {
    register_rest_field( 'produit', 'donnees_timber', array(
        'get_callback' => function ( $post ) {
            $produit = Timber::get_post( $post['id'] );
            return $produit->to_array_public();
        },
    ) );
} );

Ce que cette transition ne couvre pas

Il faut être précis sur les limites de cette approche : elle ne traite pas le rendu côté serveur d’un framework JavaScript. Le prototype React de l’équipe produit consomme l’API en client-side rendering pur, sans Next.js ni aucune couche de rendu serveur. C’est un choix assumé pour ce projet, mais une équipe visant le SEO sur ces pages devrait étudier une solution avec rendu serveur ou statique, ce qui sort du périmètre de cette architecture intermédiaire.

Les points de friction rencontrés

  • Les méthodes Twig utilisant des filtres personnalisés (|prix_formate) ont dû être dupliquées en PHP pur côté modèle pour rester utilisables par l’API
  • Certaines fiches techniques référençaient des fichiers PDF liés en dur dans le contenu Twig, invisibles pour l’API tant qu’ils n’étaient pas remontés en custom field
  • Le cache Twig (compilation des templates) devait être vidé séparément du cache de l’API lors des déploiements

Un thème Timber bien construit n’est pas un thème « prêt pour le headless », c’est un thème dont les données sont déjà rangées assez proprement pour qu’un headless devienne une option plutôt qu’une réécriture.

Après quatre semaines

La fiche produit a été le seul type de contenu converti dans ce sprint, volontairement. L’équipe a préféré valider la méthode sur un cas concret avant de généraliser aux catégories et aux fiches techniques, prévues pour les mois suivants. Le thème classique n’a subi aucune régression visible pendant toute l’opération, ce qui était la condition posée dès le départ par la direction produit.

Pour la suite

Cette bascule progressive montre qu’un headless ne s’oppose pas forcément à un thème existant : il peut en être le prolongement naturel si la donnée a déjà été correctement isolée de sa présentation. Timber et Twig ne sont pas des outils headless, mais ils imposent une hygiène de code qui rend la transition beaucoup moins coûteuse le jour où elle devient nécessaire.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi