Le WordPress d'aujourd'hui, décodé pour les développeurs

Extensions

wp_after_insert_post contre save_post : quand utiliser ce hook plus récent

Deux hooks se déclenchent quand un article est enregistré, mais pas au même moment ni avec les mêmes garanties. Voici la différence qui évite des bugs difficiles à reproduire.

Par WordPress Développement • 27 septembre 2023 • 5 min de lecture • Aucun commentaire
wp_after_insert_post contre save_post : quand utiliser ce hook plus récent
add_action( 'save_post', 'ma_fonction' );
add_action( 'wp_after_insert_post', 'ma_fonction' );

Ces deux lignes déclenchent, en apparence, la même fonction au même moment : juste après l’enregistrement d’un article. Pourtant, un développeur qui a déjà tenté de lire une métadonnée ou un terme de taxonomie fraîchement associé depuis un hook save_post, sans succès, sait que ce n’est pas toujours vrai. La différence entre ces deux hooks tient au moment exact de leur déclenchement dans la séquence d’enregistrement, et elle peut expliquer des bugs qui ne se manifestent que dans certains contextes précis.

Ce que fait réellement save_post

Le hook save_post se déclenche à l’intérieur de la fonction wp_insert_post(), juste après l’écriture de la ligne principale dans la table wp_posts. À ce stade, les métadonnées personnalisées et les termes de taxonomie ne sont pas nécessairement tous écrits : sur l’écran d’édition classique, ce sont justement les fonctions accrochées à save_post elles-mêmes qui se chargent d’enregistrer les métadonnées des metaboxes, via update_post_meta(). Autrement dit, à l’intérieur d’un même hook save_post, l’ordre de priorité entre plusieurs fonctions accrochées détermine si une métadonnée écrite par l’une est déjà disponible pour l’autre.

Ce que garantit wp_after_insert_post

L'essentiel à retenir : save_post peut s'exécuter avant que les métadonnées associées ne soient toutes écrites ; wp_after_insert_post attend que termes et méta soient posés ; Le choix du bon hook évite des bugs qui n'apparaissent qu'en REST

Introduit dans WordPress 5.6, sorti en décembre 2020, le hook wp_after_insert_post se déclenche après save_post, une fois que WordPress considère que l’insertion complète du post, y compris ses métadonnées et ses termes associés dans le contexte de l’appel en cours, est terminée. Sa signature transmet en plus un paramètre $update et l’objet $post_before, utile pour comparer l’état avant et après modification :

add_action( 'wp_after_insert_post', function( $post_id, $post, $update, $post_before ) {
    $categorie = wp_get_post_terms( $post_id, 'category' );

    if ( ! empty( $categorie ) ) {
        // Fiable ici : la relation de taxonomie est posée.
        error_log( 'Catégorie confirmée : ' . $categorie[0]->name );
    }
}, 10, 4 );

Ce hook a été conçu en priorité pour l’API REST, où la création d’un article passe par plusieurs appels distincts : wp_insert_post() pour le contenu, puis des appels séparés pour les termes et les métadonnées via les champs enregistrés avec register_rest_field() ou register_post_meta(). Avant l’introduction de ce hook, il n’existait aucun point d’accroche fiable garantissant que toute cette séquence REST était terminée.

Un exemple concret de bug évité

Un cas typique : une extension qui envoie une notification à un service externe dès qu’un article est publié avec sa catégorie. Accrochée à save_post, cette notification peut partir avant que la catégorie ne soit associée, si la requête REST assigne les termes après l’appel initial de création. Le message envoyé contiendrait alors une catégorie vide, un comportement difficile à reproduire depuis l’écran d’édition classique, où l’ordre d’exécution diffère légèrement de celui de l’API REST.

Quand chacun reste pertinent

  • save_post reste adapté pour enregistrer soi-même des métadonnées personnalisées issues d’une metabox de l’écran d’édition classique : c’est son usage historique, et il continue de fonctionner correctement dans ce contexte précis.
  • wp_after_insert_post devient préférable dès qu’une action dépend de données annexes (termes, métadonnées enregistrées ailleurs) et doit fonctionner de façon identique, que l’article soit créé depuis l’éditeur classique ou via l’API REST.
  • Les variantes spécifiques par type de contenu, save_post_{post_type}, existent aussi pour save_post, mais wp_after_insert_post ne propose pas d’équivalent filtré par type : un test manuel sur $post->post_type reste nécessaire à l’intérieur du callback.

Piège à éviter : la double invocation lors d’une modification

Comme save_post, le hook wp_after_insert_post se déclenche aussi bien à la création qu’à la modification d’un article. Le paramètre $update, transmis en booléen, permet de distinguer les deux cas sans avoir à comparer manuellement $post->post_date et $post->post_modified :

add_action( 'wp_after_insert_post', function( $post_id, $post, $update ) {
    if ( $update ) {
        return; // On ne veut agir qu'à la création.
    }

    // Traitement réservé à la création initiale.
}, 10, 3 );

En résumé

Le choix entre ces deux hooks ne relève pas d’une préférence stylistique : save_post convient aux traitements internes à l’écran d’édition classique, tandis que wp_after_insert_post apporte une garantie de complétude nécessaire dès qu’une extension doit se comporter de façon identique entre l’éditeur classique et l’API REST. Ignorer cette distinction produit des bugs qui ne se manifestent que dans un seul des deux contextes, souvent longtemps après la mise en production initiale.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi