Aller au contenu principal
Version: 26.0.9.0

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

app/Controller/HooksController.php
<?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 :

views/services.html.twig
<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() :

views/index.html.twig
{{ hook('front-page.services') }}

Paramètres

ParamètreTypeDescription
$namestringRequis. Nom du hook. Les / sont automatiquement convertis en . (front-page/servicesfront-page.services).
$templatestringRequis. Chemin Twig du template à rendre lorsque ce hook est actif. Supporte les namespaces (@child/…, @theme/…).

Comportement

  1. Le ControllerResolver scanne automatiquement tous les contrôleurs de l'écosystème (thème, thème enfant, plugins).
  2. Pour chaque méthode annotée #[Hook], il enregistre un filtre WordPress elm.<name> via le service twig.hook.
  3. Quand {{ hook('front-page.services') }} est exécuté dans Twig, le service twig.hook déclenche apply_filters('elm.front-page.services', …).
  4. Votre méthode est appelée avec le tableau $args courant et doit retourner un tableau de variables à fusionner dans le contexte Twig.
  5. Le template déclaré dans #[Hook] remplace celui par défaut.
Préfixe 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.

child-theme/app/Controller/HooksController.php
<?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,
        ];
    }
}
child-theme/views/about.html.twig
<div class="about" style="--color-primary: {{ primaryColor|default('#000') }}">
    <h2>{{ title }}</h2>
    <p>{{ content }}</p>
</div>

Différence avec #[Component]

#[Component]#[Hook]
RôleFournit les données d'un composantSurcharge/étend un point d'extension déclaré dans un template
DéclencheurAppel de component('name') dans TwigAppel de hook('name') dans Twig
TemplateDéfini par la convention components/name.html.twigDéfini explicitement dans l'attribut
Contexte typiqueThème principalThè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 ...$args pour préserver les variables existantes.
  • Utilisez les namespaces Twig (@child/…) pour cibler précisément le bon projet source.
  • Un seul HooksController par projet suffit — regroupez-y tous les hooks du thème enfant ou du plugin.