« Pourquoi mon champ personnalisé est-il vide au moment où mon code s’exécute, alors qu’il est bien rempli une fois la page rechargée ? » Cette question, posée régulièrement par des développeurs qui découvrent le cœur de WordPress, trouve presque toujours sa réponse dans une confusion entre save_post et wp_after_insert_post, deux hooks aux noms proches mais aux moments d’exécution très différents.
Valider une annonce avant publication demande souvent de lire des champs personnalisés fraîchement saisis. Le hook choisi pour cette validation détermine directement si ces données sont déjà disponibles ou pas encore, ce qui explique bien des comportements erratiques observés en production.
save_post : un ancien de la maison
Le hook save_post existe depuis les premières versions de WordPress et se déclenche juste après l’insertion de l’article en base de données, mais avant que certains traitements associés, comme l’enregistrement de champs personnalisés par des extensions tierces, ne soient nécessairement terminés.
add_action( 'save_post', function( $post_id, $post, $update ) {
if ( $post->post_type !== 'annonce' ) {
return;
}
// Ici, certains champs personnalisés enregistrés
// par une extension peuvent ne pas encore être disponibles.
$statut = get_post_meta( $post_id, 'statut_verification', true );
}, 10, 3 );
wp_after_insert_post : arrivé plus tard, plus fiable

Introduit avec WordPress 5.6 en décembre 2020, le hook wp_after_insert_post se déclenche une fois l’ensemble du traitement d’insertion terminé, y compris l’enregistrement des taxonomies et des métadonnées associées par les extensions qui s’accrochent elles-mêmes à des hooks intermédiaires.
add_action( 'wp_after_insert_post', function( $post_id, $post, $update, $post_before ) {
if ( $post->post_type !== 'annonce' ) {
return;
}
// Ici, l'ensemble des métadonnées et taxonomies
// sont déjà enregistrées de façon fiable.
$statut = get_post_meta( $post_id, 'statut_verification', true );
}, 10, 4 );
Le tableau comparatif
| Critère | save_post | wp_after_insert_post |
|---|---|---|
| Disponible depuis | Depuis les premières versions | WordPress 5.6 (déc. 2020) |
| Moment d’exécution | Juste après l’insertion en base | Une fois tout le traitement terminé |
| Accès au post avant modification | Non fourni nativement | Fourni via le paramètre $post_before |
| Cas d’usage typique | Actions simples ne dépendant d’aucune extension tierce | Validation fiable après enregistrement complet |
Le piège des doubles déclenchements
Les deux hooks partagent un défaut commun souvent oublié : ils peuvent se déclencher plusieurs fois lors d’un même enregistrement, notamment lors d’une sauvegarde automatique ou d’une révision. Une vérification systématique du statut réel de l’article, via wp_is_post_revision(), évite d’exécuter la validation sur un contenu qui n’est pas encore définitif.
if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) ) {
return;
}
Comment choisir en pratique
- Une simple journalisation ou une notification basique :
save_postsuffit largement - Une validation qui dépend de champs personnalisés enregistrés par une extension tierce :
wp_after_insert_postdevient nécessaire - Un besoin de comparer l’état précédent et l’état actuel de l’annonce :
wp_after_insert_postseul propose le paramètre$post_before
Deux hooks aux noms voisins ne garantissent jamais un comportement identique : toujours vérifier la documentation officielle avant de supposer l’ordre d’exécution.
Un troisième acteur à connaître : rest_after_insert_{post_type}
Sur une annonce créée via l’API REST plutôt que depuis l’écran d’administration classique, un hook supplémentaire, rest_after_insert_{post_type}, se déclenche spécifiquement dans ce contexte. Un code qui ne s’accroche qu’à save_post ou wp_after_insert_post peut ainsi manquer certaines validations si une application externe crée des annonces directement via l’API, sans jamais passer par l’écran d’édition standard.
En résumé
Pour une validation d’annonce qui dépend de données enregistrées par d’autres mécanismes que le cœur de WordPress, wp_after_insert_post offre une garantie de complétude que save_post ne peut pas toujours assurer. La validation de contenu par intelligence artificielle, elle, ferait intervenir une tout autre chaîne de traitement, indépendante de ce choix de hook.