Une extension qui enregistre un script uniquement destiné au site public, mais qui se retrouve chargé aussi dans l’éditeur de blocs, provoque presque toujours le même type de bug : un script qui entre en conflit avec l’interface d’administration. La cause est souvent la même, une condition is_admin() mal comprise, utilisée pour détecter autre chose que ce qu’elle indique réellement.
WordPress s’exécute dans plusieurs contextes bien distincts, et connaître les fonctions et constantes qui les distinguent évite une bonne partie des bugs de portée liés aux hooks.
is_admin() : administration, pas privilèges
La confusion la plus répandue consiste à croire que is_admin() vérifie si l’utilisateur courant est administrateur. Ce n’est pas son rôle : cette fonction indique simplement si la requête courante cible une page de l’interface d’administration (/wp-admin/), quel que soit le rôle de la personne connectée, y compris un simple abonné qui accède à son profil.
if ( is_admin() ) {
// On est dans /wp-admin/, pas forcément un administrateur
}
// Pour vérifier réellement les droits :
if ( current_user_can( 'manage_options' ) ) {
// Ici, on vérifie une capacité, pas un contexte
}
Autre piège fréquent : une requête AJAX déclenchée depuis l’administration (via admin-ajax.php) renvoie également true pour is_admin(), ce qui surprend souvent lors de l’écriture d’un gestionnaire AJAX.
wp_doing_ajax() : distinguer l’AJAX du reste
Introduite pour clarifier justement ce cas, la fonction wp_doing_ajax() retourne true dès que la requête passe par admin-ajax.php, qu’elle soit initiée depuis le site public ou l’administration :

add_action( 'init', function () {
if ( wp_doing_ajax() ) {
return; // Ne pas charger de scripts inutiles pendant une requête AJAX
}
} );
REST_REQUEST : le contexte de l’API REST
Lorsque la requête transite par l’API REST de WordPress, la constante REST_REQUEST est définie et vaut true. Elle n’existe pas avant que le point d’entrée REST ne soit atteint, ce qui impose de toujours la tester avec defined() avant de la lire :
if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) {
// Requête passée par wp-json/
}
wp_doing_cron() et WP_CLI : les contextes serveur
Deux autres contextes complètent ce tableau : les tâches planifiées, détectables via wp_doing_cron(), et la ligne de commande, détectable via la constante WP_CLI, définie uniquement lorsque le code s’exécute via WP-CLI :
if ( wp_doing_cron() ) {
// Exécution via wp-cron.php, pas de session utilisateur active
}
if ( defined( 'WP_CLI' ) && WP_CLI ) {
// Exécution en ligne de commande, souvent sans limite de temps d'exécution classique
}
Un exemple qui combine plusieurs contextes
Une extension qui envoie une notification par courriel lors de la publication d’un article ne doit s’exécuter ni en CLI lors d’un import massif, ni en AJAX lors d’un enregistrement automatique :
add_action( 'save_post', function ( $post_id, $post, $update ) {
if ( defined( 'WP_CLI' ) && WP_CLI ) {
return; // Éviter d'envoyer des centaines de courriels lors d'un import WP-CLI
}
if ( wp_doing_ajax() && ! isset( $_POST['publier_notification'] ) ) {
return;
}
// Envoi de la notification
}, 10, 3 );
Tableau récapitulatif
| Contexte | Détection |
|---|---|
| Interface d’administration | is_admin() |
| Requête AJAX | wp_doing_ajax() |
| API REST | defined( ‘REST_REQUEST’ ) && REST_REQUEST |
| Tâche planifiée (cron) | wp_doing_cron() |
| Ligne de commande | defined( ‘WP_CLI’ ) && WP_CLI |
Un même hook peut être déclenché dans plusieurs contextes à la fois : penser qu’un hook « ne s’exécute que côté public » est une hypothèse à vérifier, jamais à supposer.
Ce que ces fonctions ne couvrent pas
Elles ne disent rien de l’ordre d’exécution des hooks entre eux, ni des priorités appliquées à un même hook par différentes extensions : c’est un sujet distinct, qui relève de la compréhension du cycle de chargement de WordPress plutôt que de la détection de contexte.
En résumé
Cinq fonctions et constantes suffisent à couvrir la quasi-totalité des contextes d’exécution que rencontre une extension WordPress. Les connaître et les tester systématiquement avant d’exécuter un traitement lourd ou sensible évite des bugs difficiles à reproduire, car ils ne se manifestent que dans un contexte précis, rarement testé manuellement.