Hook
L'attribut #[Hook] permet à un contrôleur (thème enfant, plugin…) de surcharger ou d'étendre le rendu d'un composant sans modifier le code source du thème parent. Il s'appuie sur le système de filtres WordPress et le service interne twig.hook.
Concept
Dans Elementum, un composant peut exposer un point d'extension via la fonction Twig hook() ou component(). Tout contrôleur de l'écosystème peut alors « accrocher » ce point pour :
- Remplacer le template Twig rendu par un autre,
- Injecter des variables supplémentaires dans le contexte du template.
Template Twig Contrôleur (thème enfant)
───────────── ─────────────────────────
{{ hook('front-page.services') }}
│ #[Hook('front-page.services', '@child/services.html.twig')]
│◄─────────────public function services($args): array { … }
│
└─► Rend @child/services.html.twig avec les args retournés
Utilisation
<?php namespace Elementum\Child\Controller; use Elementum\Abstract\Controller; use Elementum\Attributes\Hook; class HooksController extends Controller { #[Hook('front-page.services', '@child/services.html.twig')] public function services(array $args): array { return [ ...$args, 'title' => 'Nos services', 'content' => 'Description injectée depuis le thème enfant.', ]; } }
Le template Twig correspondant :
<section class="services"> <h2>{{ title }}</h2> <p>{{ content }}</p> </section>
Et dans le template du thème parent, le point d'extension est déclaré avec hook() :
{{ hook('front-page.services') }}
Paramètres
| Paramètre | Type | Description |
|---|---|---|
$name | string | Requis. Nom du hook. Les / sont automatiquement convertis en . (front-page/services → front-page.services). |
$template | string | Requis. Chemin Twig du template à rendre lorsque ce hook est actif. Supporte les namespaces (@child/…, @theme/…). |
Comportement
- Le
ControllerResolverscanne automatiquement tous les contrôleurs de l'écosystème (thème, thème enfant, plugins). - Pour chaque méthode annotée
#[Hook], il enregistre un filtre WordPresselm.<name>via le servicetwig.hook. - Quand
{{ hook('front-page.services') }}est exécuté dans Twig, le servicetwig.hookdéclencheapply_filters('elm.front-page.services', …). - Votre méthode est appelée avec le tableau
$argscourant et doit retourner un tableau de variables à fusionner dans le contexte Twig. - Le template déclaré dans
#[Hook]remplace celui par défaut.
elm.Le filtre WordPress sous-jacent est toujours préfixé elm.. Ainsi #[Hook('front-page.services', …)] attache le filtre elm.front-page.services.
Normalisation du nom
Les caractères / dans $name sont automatiquement convertis en . :
#[Hook('front-page/services', '@child/services.html.twig')] // équivalent à : #[Hook('front-page.services', '@child/services.html.twig')]
Exemple complet — thème enfant
Scénario : le thème parent affiche une section « À propos » via un composant. Le thème enfant veut remplacer cette section par un template personnalisé avec une couleur dynamique.
<?php namespace Elementum\Child\Controller; use Elementum\Abstract\Controller; use Elementum\Attributes\Hook; class HooksController extends Controller { #[Hook('front-page.about', '@child/about.html.twig')] public function about(array $args): array { $primaryColor = $this->customize() ->getPanel('theme_colors') ->palette ->theme_primary; return [ ...$args, 'title' => 'À propos', 'content' => 'Contenu personnalisé depuis le thème enfant.', 'primaryColor' => $primaryColor, ]; } }
<div class="about" style="--color-primary: {{ primaryColor|default('#000') }}"> <h2>{{ title }}</h2> <p>{{ content }}</p> </div>
Différence avec #[Component]
#[Component] | #[Hook] | |
|---|---|---|
| Rôle | Fournit les données d'un composant | Surcharge/étend un point d'extension déclaré dans un template |
| Déclencheur | Appel de component('name') dans Twig | Appel de hook('name') dans Twig |
| Template | Défini par la convention components/name.html.twig | Défini explicitement dans l'attribut |
| Contexte typique | Thème principal | Thème enfant, plugin tiers |
Bonnes pratiques
- Nommez les hooks de manière descriptive en utilisant le format
section.element(ex:front-page.hero,header.navigation). - Retournez toujours un tableau depuis la méthode ; fusionnez avec
...$argspour préserver les variables existantes. - Utilisez les namespaces Twig (
@child/…) pour cibler précisément le bon projet source. - Un seul
HooksControllerpar projet suffit — regroupez-y tous les hooks du thème enfant ou du plugin.