Si alguna vez te has preguntado cómo es posible que un plugin modifique el comportamiento de WordPress sin tocar ni una línea de su código fuente, la respuesta está en los hooks de WordPress. Los hooks (ganchos, en español) son el mecanismo de extensión sobre el que se construye todo el ecosistema: temas, plugins y hasta el propio núcleo los usan constantemente para insertar funcionalidad o alterar datos en puntos concretos de la ejecución. Entenderlos es la frontera que separa a quien copia y pega fragmentos de código de quien realmente sabe qué está haciendo con su web. En esta guía vamos a ver qué son exactamente los actions y los filters, en qué se diferencian, cómo usarlos con ejemplos reales y funcionales, cómo controlar prioridades y argumentos, y cómo crear tus propios hooks para que tu código también sea extensible. Todo con código PHP probado que puedes adaptar a tu proyecto hoy mismo.
Qué son los hooks de WordPress y por qué existen
WordPress se diseñó desde el principio con una regla de oro: nunca modificar el núcleo. Si cada desarrollador editase los archivos de wp-includes para cambiar un comportamiento, cada actualización borraría esos cambios y mantener una web sería una pesadilla. La solución fue sembrar el código del núcleo con miles de puntos de enganche: momentos concretos de la ejecución en los que WordPress se detiene un instante y pregunta «¿alguien quiere hacer algo aquí?».
Eso es un hook: un punto de extensión con nombre propio. Cuando WordPress carga una página ejecuta, en orden, hooks como init, wp_loaded, template_redirect o wp_head. Tu código puede «engancharse» a cualquiera de ellos registrando una función de callback, y WordPress la ejecutará en ese momento exacto sin que tengas que tocar nada más.
El sistema descansa sobre dos familias:
- Actions (acciones): exécutent du code à un moment donné. Ils ne retournent rien ; ils servent à faire des choses (envoyer un e-mail, mettre un script en file d'attente, enregistrer un type de publication).
- Filtres : reçoivent une donnée, la modifient et la retournent. Ils servent à transformer des informations (changer le texte d'un extrait, modifier un titre, altérer une requête).
Cette distinction est la première question que vous devriez vous poser face à n'importe quel hook : est-ce que je fais quelque chose ou est-ce que je modifie quelque chose ?
Actions : exécuter du code au bon moment
Une action s'enregistre avec add_action(), qui nécessite au minimum deux paramètres : le nom du hook et la fonction que vous voulez exécuter. Voyons l'exemple classique, charger une feuille de style de la bonne manière :
<?php
function biblioweb_cargar_estilos() {
wp_enqueue_style(
'biblioweb-personalizado',
get_stylesheet_directory_uri() . '/css/personalizado.css',
array(),
'1.0.0'
);
}
add_action( 'wp_enqueue_scripts', 'biblioweb_cargar_estilos' );
Ici, nous disons à WordPress : « quand vient le moment de mettre en file d'attente les scripts et les styles du frontend (wp_enqueue_scripts), exécute ma fonction ». Un autre exemple très courant est de réagir à un événement, comme envoyer une notification lorsqu'un article est publié :
<?php
function biblioweb_avisar_publicacion( $post_id, $post ) {
// Evitamos revisiones y autoguardados.
if ( wp_is_post_revision( $post_id ) ) {
return;
}
$asunto = 'Nueva entrada publicada: ' . $post->post_title;
$mensaje = 'Se ha publicado una entrada. Revísala aquí: ' . get_permalink( $post_id );
wp_mail( 'editor@tudominio.com', $asunto, $mensaje );
}
add_action( 'publish_post', 'biblioweb_avisar_publicacion', 10, 2 );
Notez les deux derniers paramètres de add_action(): le 10 est la priorité et le 2 indique combien d'arguments notre fonction accepte. Nous les verrons en détail plus tard, car ils sont la cause de 90 % des erreurs avec les hooks.
Actions indispensables à connaître
init: WordPress est déjà chargé ; ici sont enregistrés les types de publication personnalisés, les taxonomies et les shortcodes.wp_enqueue_scripts: point correct pour mettre en file d'attente le CSS et le JS du frontend.admin_inityadmin_menu: équivalents pour la zone d'administration.wp_headywp_footer: impriment du contenu dans le<head>et avant de fermer le<body>.save_post: se déclenche lors de l'enregistrement de tout article ; idéal pour traiter les métadonnées.wp_loginyuser_register: réagissent à la connexion et à l'inscription des utilisateurs.
Filtres : modifier des données avant qu'elles ne soient utilisées
Un filtre fonctionne de la même manière qu'une action avec une différence cruciale : votre fonction reçoit une valeur et doit le retourner, modifié ou non. Si vous oubliez le return, la donnée arrive vide à sa destination et vous casserez quelque chose (extraits vides, titres disparus…). C'est l'erreur la plus courante lorsque l'on débute avec les hooks WordPress.
Exemple réel : modifier la longueur de l'extrait et le texte « lire la suite » :
<?php
function biblioweb_longitud_extracto( $longitud ) {
return 30; // palabras
}
add_filter( 'excerpt_length', 'biblioweb_longitud_extracto' );
function biblioweb_leer_mas( $more ) {
return '… <a href="' . esc_url( get_permalink() ) . '">Seguir leyendo</a>';
}
add_filter( 'excerpt_more', 'biblioweb_leer_mas' );
Un autre cas très utile : ajouter automatiquement un avis à la fin du contenu de chaque article, uniquement sur le frontend :
<?php
function biblioweb_nota_final( $content ) {
if ( is_singular( 'post' ) && in_the_loop() && is_main_query() ) {
$nota = '<p class="nota-final">¿Te ha resultado útil? Compártelo o déjanos un comentario.</p>';
return $content . $nota;
}
return $content;
}
add_filter( 'the_content', 'biblioweb_nota_final' );
Observez les vérifications conditionnelles : the_content s'applique dans de nombreux contextes (flux, widgets, pages), et filtrer sans conditions finit par afficher votre note là où elle ne devrait pas. Toujours retourner $content à la fin, même si vous ne le modifiez pas, c'est obligatoire.
Filtres que vous utiliserez encore et encore
the_contentythe_title: le corps et le titre des articles.excerpt_lengthyexcerpt_more: contrôle de l'extrait.body_class: ajoute des classes CSS au<body>.upload_mimes: permet (ou bloque) les types de fichiers dans la médiathèque.wp_mail_fromywp_mail_from_name: expéditeur des e-mails WordPress.login_errors: message d'erreur de connexion (utile pour ne pas donner d'indices aux attaquants).
Priorité et arguments : les deux nombres qui changent tout
Tant add_action() comme add_filter() acceptent quatre paramètres :
add_filter( 'nombre_del_hook', 'mi_funcion', $prioridad, $num_argumentos );
| Paramètre | Valeur par défaut | Ce qu'il contrôle |
|---|---|---|
| Priorité | 10 | L'ordre d'exécution : plus le nombre est petit, plus tôt il s'exécute. Avec la même priorité, c'est celui qui a été enregistré en premier qui l'emporte. |
| Nombre d'arguments | 1 | Combien de paramètres du hook votre fonction de rappel reçoit-elle. Si le hook en passe 3 et que vous en déclarez 1, vous ne recevrez que le premier. |
La priorité compte lorsque plusieurs plugins manipulent la même donnée. Si votre filtre sur the_content doit s'exécuter après qu'un autre plugin ait fait son travail, utilisez une priorité élevée (par exemple 99). Si vous avez besoin de devancer tout le monde, utilisez 1. Le nombre d'arguments, quant à lui, doit correspondre à ce que vous déclarez dans la signature de votre fonction : si vous mettez 10, 3 mais votre fonction n'accepte qu'un seul paramètre, PHP lancera une erreur fatale.
Pour désaccrocher une fonction, il existe remove_action() y remove_filter(), avec une condition stricte : il faut passer exactement le même nom de fonction et la même priorité que celle avec laquelle elle a été enregistrée :
<?php
// Quitar el generador de versión del head (lo añade el core con prioridad por defecto).
remove_action( 'wp_head', 'wp_generator' );
Comment créer vos propres hooks personnalisés
Voici le saut de niveau : en plus de consommer des hooks, vous pouvez en créer. Si vous développez un thème ou un plugin, parsemez votre code de do_action() y apply_filters() permet à d'autres (ou à vous-même, à l'avenir) de l'étendre sans le toucher. C'est ainsi que fonctionne WooCommerce, et c'est pourquoi son écosystème est gigantesque.
Une action personnalisée se crée avec do_action():
<?php
// En tu plugin, tras procesar un pedido de ejemplo:
function biblioweb_procesar_solicitud( $solicitud_id ) {
// ... lógica principal ...
// Punto de extensión: cualquiera puede engancharse aquí.
do_action( 'biblioweb_solicitud_procesada', $solicitud_id );
}
// Otro desarrollador (u otro archivo) se engancha:
add_action( 'biblioweb_solicitud_procesada', function ( $solicitud_id ) {
error_log( 'Solicitud procesada: ' . $solicitud_id );
} );
Et un filtre personnalisé, avec apply_filters(), qui définit la valeur par défaut et l'offre à quiconque souhaite la modifier :
<?php
function biblioweb_obtener_limite() {
$limite = 25;
// Nombre del filtro, valor por defecto y argumentos extra opcionales.
return apply_filters( 'biblioweb_limite_resultados', $limite );
}
// Cualquier otro código puede ajustarlo sin tocar tu función:
add_filter( 'biblioweb_limite_resultados', function ( $limite ) {
return 50;
} );
Deux bonnes pratiques : préfixez toujours vos hooks avec le nom de votre projet pour éviter les collisions, et documentez les arguments passés par chacun. Un hook non documenté est un hook que personne n'utilisera.
Où placer le code de vos hooks
Vous avez trois options raisonnables, de la moins à la plus recommandée selon le cas :
- Le functions.php d'un thème enfant : valable pour les réglages liés au design (extraits, classes du body). Si vous changez de thème, vous les perdez.
- Un plugin de snippets : l'option la plus confortable pour la plupart. Des outils comme WPCode, le gestionnaire de snippets que nous avons analysé en profondeur, vous permettent d'activer et de désactiver chaque fragment séparément, avec une validation de syntaxe qui évite de faire tomber le site à cause d'un point-virgule.
- Un plugin personnalisé : la bonne pratique pour les fonctionnalités qui doivent survivre au thème : types de publication personnalisés, intégrations, logique métier.
Ce que vous ne devez jamais faire, c'est éditer le functions.php du thème parent ni, bien sûr, les fichiers du cœur. Si vous débutez et ne maîtrisez pas encore les plugins essentiels pour démarrer avec WordPress, commencez par là avant de vous lancer dans le code.
Erreurs courantes lors de l'utilisation des hooks
- Oublier le return dans un filtre. Le symptôme typique : contenu ou titres qui disparaissent. Tout filtre retourne toujours une valeur.
- S'accrocher trop tôt. Si vous appelez des fonctions utilisateur avant de
initou à des fonctions de template avant dewp, vous obtiendrez des erreurs ou des valeurs vides. Chaque hook a son moment dans le cycle de chargement. - Ne pas déclarer les arguments. Enregistrer
add_action( 'save_post', 'mi_funcion', 10, 3 )avec une fonction qui n'accepte qu'un seul paramètre provoque une erreur fatale en PHP 8. - Boucles infinies. Appeler
wp_update_post()à l'intérieur d'un callback desave_postredéclenchesave_post. On l'évite en supprimant le hook avant la mise à jour et en le rajoutant après. - Callbacks anonymes que vous ne pouvez pas ensuite supprimer. Les fonctions anonymes sont pratiques, mais
remove_filter()ne peut pas les supprimer facilement. Pour le code que d'autres devraient pouvoir désactiver, utilisez des fonctions nommées.
Pour explorer quels hooks existent et quels arguments ils passent, la référence officielle de developer.wordpress.org sur les hooks est la carte définitive : elle inclut la liste complète des actions et filtres du cœur avec leur documentation.
Questions fréquentes
Quelle est la différence réelle entre une action et un filtre ?
Une action exécute du code à un point du flux et ne retourne rien : elle sert à faire des choses. Un filtre reçoit une donnée, peut la modifier et est obligé de la retourner : il sert à transformer des informations. En interne, les deux utilisent le même système (en fait add_action() appelle add_filter()), mais conceptuellement, il convient de les traiter comme des outils distincts.
Puis-je utiliser des hooks sans savoir programmer ?
Vous pouvez utiliser des fragments déjà écrits en les copiant dans un plugin de snippets comme WPCode, qui valide la syntaxe avant d'enregistrer. Cependant, comprendre au moins ce que fait chaque ligne vous évitera de coller du code malveillant ou obsolète. Les hooks WordPress sont du PHP : une base minimale vous donnera beaucoup d'autonomie.
Combien de hooks WordPress a-t-il ?
Le cœur dépasse les 3 000 entre actions et filtres, et ce chiffre augmente à chaque version. À cela s'ajoutent ceux enregistrés par vos plugins et votre thème : WooCommerce, par exemple, en ajoute des centaines. Il n'est pas nécessaire de les mémoriser : il suffit de connaître la douzaine habituelle et de savoir chercher le reste dans la documentation officielle.
Les hooks affectent-ils les performances de mon site web ?
Le système en lui-même est très efficace ; ce qui pénalise, c'est ce que vous faites à l'intérieur du callback. Une requête lourde accrochée à init s'exécutera à chaque chargement de page. Accrochez votre code au hook le plus spécifique possible et utilisez des conditionnelles pour sortir rapidement quand il n'y a pas lieu d'agir.
Conclusion
Les hooks WordPress sont le langage dans lequel le cœur, les thèmes et les plugins communiquent. Maîtriser la paire actions et filtres vous permet de personnaliser pratiquement n'importe quel comportement sans toucher au code source et sans crainte des mises à jour : mettre en file d'attente des ressources, réagir à des événements, transformer du contenu et, lorsque vous vous lancerez dans le développement, offrir vos propres points d'extension avec do_action() y apply_filters(). Commencez par reproduire les exemples de ce guide dans un environnement de test ou via un gestionnaire de snippets, faites attention aux priorités et au retour des filtres, et consultez la documentation officielle lorsque vous avez des doutes sur les arguments passés par un hook. À partir de là, chaque problème de personnalisation que vous rencontrerez dans WordPress aura presque toujours la même réponse : il y a un hook pour ça.