# Rendre votre extension extensible : concevoir ses propres hooks

> Un intégrateur m'a demandé un jour « comment je modifie ce bout de HTML sans toucher à votre code source ? » Bonne question : si l'extension n'expose aucun hook, la réponse est qu'il ne peut pas.

- Auteur : Clément Hadrot
- Publié le : 2021-04-26
- Mis à jour le : 2021-04-26
- Catégorie : Extensions
- URL : https://wpmoderne.dev.wordpress-developpement.fr/extensions/rendre-extension-extensible-concevoir-hooks/

## L’essentiel

- Chaque zone de sortie ou de décision mérite d'être filtrable, pas seulement les données finales
- Un nom de hook préfixé et documenté évite les collisions et les mauvaises surprises
- Documenter les arguments transmis fait gagner un temps précieux aux développeurs tiers

En développant une extension de réservation pour des chambres d'hôtes, destinée à être réutilisée sur plusieurs sites d'une même agence, j'ai vite réalisé qu'un intégrateur freelance ne travaillerait jamais sur mon code source directement. Chaque site avait ses spécificités visuelles et métier. La question qu'il m'a posée, presque en passant, a orienté toute l'architecture du plugin : « comment je modifie ce bout de HTML sans toucher à votre code ? »

La réponse tient dans la conception volontaire de points d'extension, avec `do_action()` et `apply_filters()`, pensés comme une véritable API interne plutôt que comme un ajout de dernière minute.

## Repérer les bons endroits pour un hook

Toutes les lignes de code ne méritent pas un hook : en ajouter partout nuit à la lisibilité et complique la maintenance. Trois catégories de code se prêtent particulièrement bien à l'exposition d'un point d'extension.

- Une sortie HTML destinée à être personnalisée visuellement (avant, après, ou en remplacement complet d'un bloc)
- Une valeur calculée qui pourrait légitimement varier selon le contexte métier d'un site (un tarif, une durée, une capacité)
- Un moment clé du cycle de vie d'une donnée (avant sauvegarde, après confirmation, avant annulation)

Pour ce plugin de réservation, le calcul du tarif final s'est révélé être le point d'extension le plus demandé par les intégrateurs : chaque hôte pratiquait des règles de majoration différentes selon la saison, ce que le cœur du plugin ne pouvait pas anticiper.

## Filtrer une valeur calculée avec apply_filters

```
function sejours_calculer_tarif_final( $tarif_base, $chambre_id, $dates ) {
    $tarif = $tarif_base;

    // logique interne au plugin, calcul de base

    /**
     * Filtre le tarif final d'une réservation avant affichage.
     *
     * @param float $tarif      Tarif calculé par le plugin.
     * @param int   $chambre_id Identifiant de la chambre concernée.
     * @param array $dates      Tableau contenant 'arrivee' et 'depart'.
     */
    return apply_filters( 'sejours_tarif_final', $tarif, $chambre_id, $dates );
}
```

Transmettre `$chambre_id` et `$dates` en plus du tarif, même si le filtre pourrait techniquement fonctionner avec la seule valeur numérique, permet à un développeur tiers d'appliquer une règle conditionnelle sans avoir à recharger ces informations depuis la base de données. C'est ce contexte additionnel qui transforme un filtre basique en véritable point d'extension exploitable.

## Marquer un moment du cycle de vie avec do_action

> L'essentiel à retenir : Chaque zone de sortie ou de décision mérite d'être filtrable, pas seulement les données finales ; Un nom de hook préfixé et documenté évite les collisions et les mauvaises surprises ; Documenter les arguments transmis fait gagner un temps précieux aux développeurs tiers

```
function sejours_confirmer_reservation( $reservation_id ) {
    update_post_meta( $reservation_id, '_sejours_statut', 'confirmee' );

    /**
     * Se déclenche juste après la confirmation d'une réservation.
     *
     * @param int $reservation_id Identifiant de la réservation confirmée.
     */
    do_action( 'sejours_reservation_confirmee', $reservation_id );
}
```

Ce hook a permis à un intégrateur, sur un site particulier, de brancher l'envoi automatique d'un SMS de confirmation via un service tiers, sans qu'une seule ligne du plugin lui-même n'ait besoin d'être modifiée. C'est exactement l'objectif recherché : le cœur du plugin reste identique sur tous les sites, seule une extension légère et spécifique à chaque client vient se greffer dessus.

## Nommer et préfixer sans ambiguïté

Un nom de hook générique comme `calculer_tarif` entrerait presque certainement en collision avec une autre extension installée sur le même site. La règle que j'applique systématiquement : préfixer chaque hook avec un identifiant court et unique du plugin, cohérent avec le préfixe déjà utilisé pour les fonctions et les options.

```
// À éviter : trop générique, risque de collision
apply_filters( 'calculer_tarif', $tarif );

// À privilégier : préfixé, explicite
apply_filters( 'sejours_tarif_final', $tarif, $chambre_id, $dates );
```

Ce même préfixe doit rester strictement identique partout dans le plugin, y compris dans les noms d'options, de tables et de classes. Un intégrateur qui explore le code source pour comprendre les points d'extension disponibles s'appuie largement sur cette cohérence pour naviguer rapidement.

## Documenter les hooks pour de vrai

Un hook non documenté est, dans les faits, un hook qui n'existe pas pour la plupart des développeurs tiers pressés. Le bloc de commentaire PHPDoc placé juste avant chaque `do_action` ou `apply_filters`, comme dans les exemples précédents, constitue un minimum. Pour ce plugin, distribué à plusieurs agences partenaires, j'ai complété cette documentation en code par une liste centralisée dans un fichier `HOOKS.md` à la racine, recensant chaque hook avec sa description, ses arguments et un exemple d'utilisation.

> Un hook que vous n'osez pas documenter parce que son comportement est instable ou mal défini est probablement un hook qui n'est pas encore prêt à être exposé publiquement.

## En résumé

Concevoir ses propres hooks demande d'anticiper, dès l'architecture initiale, les endroits où une personnalisation légitime sera nécessaire sans passer par une modification du code source. Ce travail se fait en amont, rarement à la demande, et c'est justement ce qui distingue une extension pensée pour être étendue d'une extension qui se contente de fonctionner isolément.
