Index des hooks WordPress
Un index consultable des actions et filtres WordPress que les développeurs utilisent réellement — avec la signature add_action/add_filter exacte, le moment où le hook se déclenche, un exemple fonctionnel et le piège qui fait mal.
39 hooks, avec la signature add_action / add_filter exacte, le moment où il se déclenche, un exemple fonctionnel, et le piège qui prend tout le monde au dépourvu. 1 sont marqués comme non vérifiés — nous n'avons pas confronté leur nombre d'arguments au code source de WordPress, et nous préférons le signaler plutôt que de présenter une supposition comme un fait.
Cette liste n'est pas exhaustive et ne prétend pas l'être — WordPress compte des milliers de hooks. Elle couvre ceux que l'on utilise réellement.
S'exécute une fois WordPress entièrement chargé, mais avant l'envoi du moindre en-tête. L'endroit standard pour enregistrer les types de publication personnalisés, les taxonomies et les règles de réécriture.
Se déclenche
À chaque requête, côté public comme côté admin, après le chargement du cœur, des extensions et du thème.
Signature
add_action( 'init', 'my_callback' );Exemple
add_action( 'init', function () {
register_post_type( 'book', array(
'public' => true,
'label' => 'Books',
'show_in_rest' => true, // required for the block editor
) );
} );Le piège
init s'exécute à CHAQUE requête, y compris AJAX, REST et cron. Y faire quoi que ce soit de lent (une requête HTTP, une requête lourde) pèse sur absolument tous les chargements de page. Par ailleurs : l'utilisateur courant est disponible ici, mais vous ne pouvez rien afficher — les en-têtes n'ont pas encore été envoyés, mais ils sont sur le point de l'être.
S'exécute une fois le thème chargé. Le bon endroit pour add_theme_support(), add_image_size() et l'enregistrement des menus de navigation.
Se déclenche
Après le chargement du functions.php du thème, AVANT init.
Signature
add_action( 'after_setup_theme', 'my_callback' );Exemple
add_action( 'after_setup_theme', function () {
add_theme_support( 'post-thumbnails' );
add_theme_support( 'title-tag' );
add_image_size( 'card', 600, 400, true ); // true = hard crop
} );Le piège
Enregistrer les tailles d'images sur init plutôt qu'ici fonctionne par accident dans la plupart des cas, puis échoue mystérieusement dans certains. Utilisez after_setup_theme — c'est précisément à ça qu'il sert.
S'exécute une fois toutes les extensions actives chargées. Le premier point sûr pour interagir avec une autre extension.
Se déclenche
Après l'inclusion de tous les fichiers d'extensions, avant le chargement du thème.
Signature
add_action( 'plugins_loaded', 'my_callback' );Le piège
L'utilisateur courant n'est PAS encore disponible ici — wp_get_current_user() ne fonctionnera pas de façon fiable. Si vous avez besoin de l'utilisateur, utilisez init.
S'exécute une fois WordPress entièrement chargé — les extensions, le thème, init et l'utilisateur sont tous prêts.
Se déclenche
Après init et après la mise en place de l'utilisateur courant.
Signature
add_action( 'wp_loaded', 'my_callback' );S'exécute au début de chaque requête d'administration. Utilisé pour register_setting(), les vérifications de permissions et les redirections dans l'admin.
Se déclenche
À chaque requête côté administration.
Signature
add_action( 'admin_init', 'my_callback' );Le piège
Il se déclenche aussi sur les requêtes admin-ajax.php, qui ne sont pas vraiment des « écrans d'administration ». Si votre callback suppose l'existence d'un écran, protégez-le avec wp_doing_ajax().
Le seul bon endroit pour mettre en file d'attente le CSS et le JavaScript côté public.
Se déclenche
Au chargement des pages côté public, avant le rendu du head.
Signature
add_action( 'wp_enqueue_scripts', 'my_callback' );Exemple
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_style(
'child-style',
get_stylesheet_uri(),
array( 'parent-style' ), // load AFTER the parent
wp_get_theme()->get( 'Version' ) // cache-bust on version change
);
} );Le piège
Malgré son nom, il gère aussi bien les STYLES que les scripts — il n'existe pas de hook wp_enqueue_styles, et certains perdent un temps fou à en chercher un. Par ailleurs : il ne se déclenche pas dans l'admin (utilisez admin_enqueue_scripts) ni dans l'éditeur de blocs (utilisez enqueue_block_editor_assets).
Mettre en file d'attente le CSS/JS dans l'admin. Reçoit le suffixe de hook de l'écran courant, ce qui permet de charger les ressources sur un seul écran.
Se déclenche
Au chargement des pages d'administration.
Signature
add_action( 'admin_enqueue_scripts', 'my_callback' ); // receives $hook_suffixExemple
add_action( 'admin_enqueue_scripts', function ( $hook ) {
if ( 'settings_page_my-plugin' !== $hook ) {
return; // do not load our JS on every admin screen
}
wp_enqueue_script( 'my-admin', plugins_url( 'admin.js', __FILE__ ), array(), '1.0', true );
} );Le piège
Ne pas filtrer sur $hook est de loin la cause la plus fréquente d'une extension qui casse des écrans d'administration sans rapport. Chargez vos ressources là où elles sont nécessaires, et nulle part ailleurs.
Mettre en file d'attente des ressources uniquement dans l'éditeur de blocs (Gutenberg) — pas côté public, pas dans le reste de l'admin.
Se déclenche
Au chargement de l'éditeur de blocs.
Signature
add_action( 'enqueue_block_editor_assets', 'my_callback' );Affiche du contenu dans le <head>. Utilisé pour les balises meta et le CSS critique en ligne.
Se déclenche
À l'intérieur du <head>, côté public.
Signature
add_action( 'wp_head', 'my_callback' );Le piège
Ne mettez PAS en file d'attente de scripts ou de styles ici — utilisez wp_enqueue_scripts, qui laisse WordPress gérer les dépendances et la déduplication. Injecter une balise <script> directement dans wp_head contourne tout cela, et c'est pour ça que tant de sites chargent jQuery trois fois.
Affiche du contenu juste avant </body>. Le bon endroit pour les extraits d'analytics et le balisage différé.
Se déclenche
À la fin de la page côté public.
Signature
add_action( 'wp_footer', 'my_callback' );Le piège
Un thème qui oublie d'appeler wp_footer() casse la barre d'administration, casse toute extension qui met en file d'attente un script de pied de page, et entraîne un rejet automatique lors de la revue des thèmes sur wordpress.org.
Filtre le contenu de l'article juste avant son affichage. L'endroit habituel pour ajouter du balisage au début ou à la fin d'un article.
Se déclenche
Chaque fois que the_content() est appelée.
Signature
add_filter( 'the_content', 'my_callback' ); // receives $contentExemple
add_filter( 'the_content', function ( $content ) {
if ( ! is_singular( 'post' ) || ! in_the_loop() || ! is_main_query() ) {
return $content; // <- the guard everyone forgets
}
return $content . '<p class="cta">Enjoyed this? Read more.</p>';
} );Le piège
Cela s'exécute bien plus souvent qu'on ne le croit — dans les widgets, dans les réponses REST, dans la génération d'extraits de certaines extensions, et une fois par article dans une boucle sur une archive. Sans la protection is_singular / in_the_loop / is_main_query, votre CTA apparaît quinze fois sur la page d'accueil du blog et dans le flux RSS. C'est le filtre le plus mal utilisé de WordPress.
Filtre le titre de l'article avant son affichage.
Se déclenche
Chaque fois que the_title() ou get_the_title() est appelée.
Signature
add_filter( 'the_title', 'my_callback', 10, 2 ); // receives $title, $post_idLe piège
Il se déclenche aussi pour les titres du menu d'administration, des menus de navigation et du <title> du document. Le filtrer sans condition renommera des éléments à des endroits que vous n'aviez pas prévus.
Définit le nombre de MOTS que contient un extrait généré automatiquement. La valeur par défaut est 55.
Se déclenche
Lorsque WordPress génère un extrait pour un article qui n'a pas d'extrait manuel.
Signature
add_filter( 'excerpt_length', 'my_callback' ); // receives $length (words)Exemple
add_filter( 'excerpt_length', function ( $length ) {
return 25;
}, 999 ); // high priority: many themes set this too, and last one winsLe piège
Il n'a aucun effet sur les articles qui ont un extrait MANUEL — ceux-ci sont utilisés tels quels. Et beaucoup de thèmes définissent eux-mêmes ce filtre, si bien qu'il faut souvent un numéro de priorité élevé pour l'emporter.
Modifie la chaîne ajoutée à la fin d'un extrait tronqué. La valeur par défaut est " […]".
Se déclenche
Lorsqu'un extrait généré automatiquement est tronqué.
Signature
add_filter( 'excerpt_more', 'my_callback' ); // receives $moreModifie une requête AVANT son exécution. La bonne façon de changer ce qui apparaît sur une archive — bien meilleure qu'une seconde WP_Query.
Se déclenche
Après l'analyse des variables de requête, avant la construction du SQL.
Signature
add_action( 'pre_get_posts', 'my_callback' ); // receives WP_Query $query (by reference)Exemple
add_action( 'pre_get_posts', function ( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return; // <- both guards are mandatory
}
if ( $query->is_category() ) {
$query->set( 'posts_per_page', 12 );
}
} );Le piège
Il s'exécute aussi dans l'ADMIN, et il s'exécute pour CHAQUE requête, y compris les menus, les widgets et la bibliothèque de médias. Omettez les protections is_admin() et is_main_query() et vous modifierez en silence ce qu'affiche la liste des articles dans l'admin — un bug vraiment difficile à remonter. À noter aussi : modifiez $query, ne retournez rien.
Filtre la clause SQL WHERE brute d'une requête.
Se déclenche
Pendant l'assemblage du SQL de la requête.
Signature
add_filter( 'posts_where', 'my_callback', 10, 2 ); // receives $where, WP_Query $queryLe piège
Vous écrivez du SQL brut. Protégez toujours avec $query->is_main_query() et utilisez toujours $wpdb->prepare() pour toute donnée saisie par l'utilisateur. C'est le moyen le plus rapide d'introduire une injection SQL dans un site WordPress.
Filtre le nombre total d'articles trouvés par une requête — c'est à partir de ce nombre qu'est calculée la pagination.
Se déclenche
Après l'exécution de la requête, avant le calcul de la pagination.
Signature
add_filter( 'found_posts', 'my_callback', 10, 2 ); // receives $found_posts, WP_Query $queryDéfinit la taille en pixels au-delà de laquelle WordPress réduit un fichier téléversé et sert une copie « -scaled » à la place de votre original. Valeur par défaut : 2560.
Se déclenche
Au téléversement, lorsque WordPress détermine si une image est « grande ».
Signature
add_filter( 'big_image_size_threshold', 'my_callback' ); // receives int $thresholdExemple
// Serve originals at full resolution — no -scaled copy.
add_filter( 'big_image_size_threshold', '__return_false' );
// Or just raise the ceiling:
add_filter( 'big_image_size_threshold', function () {
return 3840;
} );Le piège
C'est de loin la cause la plus fréquente du « mon image est floue après l'avoir téléversée sur WordPress », et presque personne ne sait que ça existe. Votre original est toujours sur le disque — il n'est simplement jamais servi. À noter : cela s'applique au côté le PLUS LONG, et n'affecte que les images téléversées après l'activation du filtre.
Filtre le tableau des tailles d'images que WordPress s'apprête à générer pour un fichier téléversé. Supprimez une taille du tableau pour cesser de la générer.
Se déclenche
Au téléversement, avant la création des fichiers dérivés.
Signature
add_filter( 'intermediate_image_sizes_advanced', 'my_callback', 10, 2 ); // receives $sizes, $metadataExemple
add_filter( 'intermediate_image_sizes_advanced', function ( $sizes ) {
unset( $sizes['1536x1536'] );
unset( $sizes['2048x2048'] );
return $sizes;
} );Le piège
Supprimer une taille que votre thème UTILISE réellement fait que WordPress se rabat sur l'original en pleine taille — ce qui est pire que l'espace disque économisé. Et cela n'empêche que la création de NOUVEAUX fichiers ; les fichiers existants restent jusqu'à ce que vous les régénériez.
Définit la qualité JPEG à laquelle WordPress ré-encode les images téléversées. Valeur par défaut : 82.
Se déclenche
Chaque fois que WordPress écrit un JPEG.
Signature
add_filter( 'jpeg_quality', 'my_callback', 10, 2 ); // receives $quality, $contextLe piège
Une qualité de 82 convient aux photographies mais est visiblement médiocre pour les captures d'écran, les logos et les images plates — ceux-ci ont des bords nets et aucun bruit photographique pour masquer les artefacts. Par ailleurs : wp_editor_set_quality est le filtre plus moderne et couvre directement les classes d'éditeur d'image ; définir les deux est courant.
Définit la qualité de sortie utilisée par les classes WP_Image_Editor (GD et Imagick).
Se déclenche
Lorsqu'une instance d'éditeur d'image définit sa qualité.
Signature
add_filter( 'wp_editor_set_quality', 'my_callback', 10, 2 ); // receives $quality, $mime_typeAjoute vos tailles d'images personnalisées au menu déroulant des tailles dans la fenêtre modale des médias et l'éditeur de blocs.
Se déclenche
Lorsque l'interface des médias construit son sélecteur de taille.
Signature
add_filter( 'image_size_names_choose', 'my_callback' ); // receives $sizesExemple
add_filter( 'image_size_names_choose', function ( $sizes ) {
return array_merge( $sizes, array( 'card' => __( 'Card', 'textdomain' ) ) );
} );Le piège
add_image_size() enregistre la taille mais ne la rend PAS sélectionnable dans l'éditeur. Toute question du type « ma taille d'image personnalisée n'apparaît pas dans le menu déroulant » vient de l'absence de ce filtre.
Inspecte ou rejette un fichier AVANT son déplacement dans le dossier des téléversements.
Se déclenche
Pendant le téléversement, avant l'écriture du fichier.
Signature
add_filter( 'wp_handle_upload_prefilter', 'my_callback' ); // receives $fileLe piège
Pour rejeter un fichier, affectez à $file['error'] une chaîne de message et retournez $file. Retourner false ou lever une exception ne fera pas ce que vous voulez.
Filtre le tableau de métadonnées (y compris les tailles générées) après le traitement d'un fichier joint.
Se déclenche
Après la création des images dérivées lors du téléversement.
Signature
add_filter( 'wp_generate_attachment_metadata', 'my_callback', 10, 2 ); // receives $metadata, $attachment_idLe piège
C'est le hook qu'utilisent les extensions d'optimisation d'images. Il peut être lent — il s'exécute après l'écriture de chaque taille d'image, et effectuer une requête HTTP ici oblige chaque téléversement à l'attendre.
Filtre les candidats srcset que WordPress génère pour une image responsive.
Se déclenche
Lors du rendu d'une image responsive.
Signature
add_filter( 'wp_calculate_image_srcset', 'my_callback', 10, 5 );Le piège
Supprimer ailleurs la taille medium_large (768w) dégrade en silence le srcset — cette taille existe presque uniquement pour l'alimenter.
Nous n'avons pas vérifié le nombre exact d'arguments de ce hook par rapport au code source de WordPress. Consultez developer.wordpress.org avant de vous y fier. Nous préférons signaler cette incertitude plutôt que de présenter discrètement une supposition comme un fait.
Enregistre les pages de menu et de sous-menu d'administration.
Se déclenche
Lors de la construction du menu d'administration.
Signature
add_action( 'admin_menu', 'my_callback' );Exemple
add_action( 'admin_menu', function () {
add_options_page(
'My Plugin',
'My Plugin',
'manage_options', // capability — NOT a role
'my-plugin',
'my_render_settings_page'
);
} );Le piège
L'argument capability est une CAPACITÉ (capability), pas un rôle. Passer « administrator » semble fonctionner (parce que les administrateurs disposent, dans certaines configurations, d'une capacité portant ce nom), puis accorde discrètement l'accès aux mauvaises personnes. Utilisez manage_options.
Affiche un avis en haut d'un écran d'administration.
Se déclenche
Au rendu d'une page d'administration.
Signature
add_action( 'admin_notices', 'my_callback' );Le piège
Il se déclenche sur CHAQUE écran d'administration. Une extension qui affiche sans condition un avis « merci d'avoir installé ! » sur tous ces écrans est le comportement le plus détesté de l'administration WordPress. Conditionnez-le, et rendez-le masquable.
S'exécute chaque fois qu'un article est créé ou mis à jour. L'endroit habituel pour enregistrer les données d'une boîte méta (meta box).
Se déclenche
Après l'écriture d'un article dans la base de données.
Signature
add_action( 'save_post', 'my_callback', 10, 3 ); // receives $post_id, $post, $updateExemple
add_action( 'save_post', function ( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( wp_is_post_revision( $post_id ) ) return;
if ( ! current_user_can( 'edit_post', $post_id ) ) return;
// ... now it is safe to save
}, 10, 1 );Le piège
Il se déclenche lors des SAUVEGARDES AUTOMATIQUES et des RÉVISIONS, en plus des véritables enregistrements. Sans les trois protections ci-dessus, vos métadonnées sont écrasées par des valeurs vides à chaque sauvegarde automatique de l'éditeur — un bug qui donne l'impression que les données disparaissent au hasard.
Enregistre les boîtes méta (meta boxes) sur l'écran d'édition d'article.
Se déclenche
Lors de la construction de l'écran d'édition.
Signature
add_action( 'add_meta_boxes', 'my_callback', 10, 2 ); // receives $post_type, $postLe piège
Les boîtes méta classiques n'apparaissent pas dans l'éditeur de blocs, sauf si celui-ci bascule en mode de compatibilité. Pour un site nativement pensé pour l'éditeur de blocs, enregistrez plutôt les métadonnées d'article avec show_in_rest et construisez un panneau dans la barre latérale.
S'exécute après qu'un utilisateur s'est connecté avec succès.
Se déclenche
Lors d'une authentification réussie.
Signature
add_action( 'wp_login', 'my_callback', 10, 2 ); // receives $user_login, WP_User $userS'exécute immédiatement après la création d'un nouvel utilisateur.
Se déclenche
Lors de l'inscription.
Signature
add_action( 'user_register', 'my_callback', 10, 2 ); // receives $user_id, $userdataFiltre le résultat de l'authentification. Retournez un WP_Error pour bloquer une connexion.
Se déclenche
Pendant la tentative de connexion.
Signature
add_filter( 'authenticate', 'my_callback', 30, 3 ); // receives $user, $username, $passwordLe piège
La priorité compte énormément ici. Le cœur de WordPress accroche ses propres vérifications aux priorités 20 et 30 — accrochez-vous trop tôt et vous vous exécutez avant même que le mot de passe ait été vérifié.
Enregistre les routes et les champs REST.
Se déclenche
Lors de l'initialisation de l'API REST.
Signature
add_action( 'rest_api_init', 'my_callback' );Exemple
add_action( 'rest_api_init', function () {
register_rest_route( 'myplugin/v1', '/items', array(
'methods' => 'GET',
'callback' => 'my_get_items',
'permission_callback' => '__return_true', // BE DELIBERATE ABOUT THIS
) );
} );Le piège
permission_callback est OBLIGATOIRE — depuis WP 5.5, l'omettre déclenche un avis, et le définir à __return_true rend le point de terminaison entièrement public. C'est acceptable pour des données réellement publiques et une faille grave pour tout le reste. Décidez, ne laissez pas la valeur par défaut.
Ajoute un intervalle de récurrence personnalisé pour wp_schedule_event().
Se déclenche
Lorsque WordPress construit sa liste des planifications disponibles.
Signature
add_filter( 'cron_schedules', 'my_callback' ); // receives $schedulesExemple
add_filter( 'cron_schedules', function ( $schedules ) {
$schedules['every_five_minutes'] = array(
'interval' => 300, // seconds
'display' => __( 'Every 5 minutes', 'textdomain' ),
);
return $schedules;
} );Le piège
WP-Cron n'est pas un vrai cron. Il ne se déclenche que lorsqu'un visiteur consulte le site, donc un site à faible trafic n'exécutera pas une planification de cinq minutes toutes les cinq minutes. Si le timing compte vraiment, désactivez WP-Cron (DISABLE_WP_CRON) et appelez wp-cron.php depuis un vrai cron système.
S'exécute immédiatement après l'enregistrement d'un commentaire.
Se déclenche
Lors de la soumission d'un commentaire.
Signature
add_action( 'comment_post', 'my_callback', 10, 3 ); // receives $comment_id, $approved, $commentdataFiltre les données d'un commentaire avant son enregistrement. Utilisé pour la détection des indésirables et la validation.
Se déclenche
Avant l'écriture du commentaire.
Signature
add_filter( 'preprocess_comment', 'my_callback' ); // receives $commentdataLe piège
Pour rejeter un commentaire ici, appelez wp_die() avec un message — retourner false ne l'empêche pas.
S'exécute sur la page de commande reçue après une validation de commande réussie.
Se déclenche
Lorsque le client arrive sur la page de remerciement.
Signature
add_action( 'woocommerce_thankyou', 'my_callback' ); // receives $order_idLe piège
Ce n'est PAS un endroit fiable pour déclencher le traitement de la commande. Il ne se déclenche que si le client atteint effectivement la page de remerciement — s'il ferme l'onglet après avoir payé, il ne s'exécute jamais. Utilisez woocommerce_payment_complete ou un hook de transition de statut de commande pour tout ce qui doit absolument se produire.
Affiche du balisage juste avant le bouton d'ajout au panier sur une page produit.
Se déclenche
Pendant le rendu de la page produit.
Signature
add_action( 'woocommerce_before_add_to_cart_button', 'my_callback' );Ajoute, supprime ou réorganise les champs de la page de commande classique.
Se déclenche
Lors de la construction du formulaire de commande.
Signature
add_filter( 'woocommerce_checkout_fields', 'my_callback' ); // receives $fieldsLe piège
Cela n'affecte que la page de commande CLASSIQUE (à base de shortcode). La nouvelle page de commande à base de blocs l'ignore complètement et se personnalise via Slot & Fill en JavaScript. Presque tout le monde s'y fait piéger la première fois.