Un contenu WordPress stocké en base commence toujours par des commentaires HTML du type <!-- wp:core/gallery -->. La tentation est grande d’écrire une expression régulière qui cherche cette chaîne dans $post->post_content pour savoir si un article contient une galerie. Cette approche fonctionne un temps, jusqu’à ce qu’un attribut contenant une accolade imprévue, un bloc imbriqué à plusieurs niveaux ou un bloc réutilisable vienne fausser la détection.
WordPress fournit depuis longtemps deux fonctions natives conçues précisément pour ce besoin : has_block() pour une simple présence, et parse_blocks() pour obtenir la structure complète et l’exploiter ensuite.
has_block() pour un test binaire
La fonction la plus directe reste has_block( $nom_du_bloc, $post ). Elle retourne un booléen, sans jamais exposer la mécanique d’analyse sous-jacente :
if ( has_block( 'core/gallery' ) ) {
wp_enqueue_style( 'lightbox-galerie' );
}
Cette fonction accepte aussi bien un identifiant d’article qu’un objet WP_Post en second argument, ou rien du tout si on l’appelle dans la boucle principale sur l’article courant. Elle gère elle-même les blocs imbriqués : un bloc groupe contenant une galerie déclenche bien true pour core/gallery, même si la galerie n’apparaît pas au premier niveau du contenu.
parse_blocks() pour aller plus loin

Dès qu’il faut non seulement détecter un bloc mais lire ses attributs, parse_blocks() devient l’outil approprié. Elle retourne un tableau de blocs, chacun avec ses clés blockName, attrs et innerBlocks :
$blocs = parse_blocks( $post->post_content );
foreach ( $blocs as $bloc ) {
if ( 'core/gallery' === $bloc['blockName'] ) {
$nombre_images = count( $bloc['attrs']['ids'] ?? [] );
// exploiter $nombre_images pour un badge, une balise meta, etc.
}
}
Attention : cette boucle simple ne descend pas dans les blocs imbriqués. Pour parcourir un contenu qui place des galeries à l’intérieur de colonnes ou de groupes, il faut une fonction récursive qui explore aussi innerBlocks à chaque niveau.
Une fonction récursive réutilisable
function compter_blocs_recursif( array $blocs, string $nom ) {
$total = 0;
foreach ( $blocs as $bloc ) {
if ( $nom === $bloc['blockName'] ) {
$total++;
}
if ( ! empty( $bloc['innerBlocks'] ) ) {
$total += compter_blocs_recursif( $bloc['innerBlocks'], $nom );
}
}
return $total;
}
$total_galeries = compter_blocs_recursif( parse_blocks( $post->post_content ), 'core/gallery' );
Cette fonction sert de base à des besoins plus larges : compter le nombre de blocs d’un type donné avant une migration, ou repérer les articles qui utilisent encore un bloc que l’on souhaite retirer du site.
Pourquoi éviter les expressions régulières ici
- Un attribut sérialisé en JSON dans le commentaire d’ouverture d’un bloc peut contenir des guillemets et des accolades imbriquées, piégeant une regex trop simple.
- Un bloc réutilisable (
core/block) ne contient pas directement le bloc recherché : il faut résoudre sonrefet analyser le contenu de l’article référencé séparément. - Un bloc peut apparaître désactivé ou commenté par erreur dans le contenu brut :
parse_blocks()reflète fidèlement la structure, y compris ses éventuelles anomalies, sans faux positif issu d’un simplestrpos().
Un cas d’usage courant : conditionner un enregistrement de script
Ce couple de fonctions est particulièrement utile pour éviter de charger un script ou un style CSS sur toutes les pages du site alors qu’un seul type de contenu utilise réellement le bloc concerné :
add_action( 'wp_enqueue_scripts', function () {
if ( has_block( 'mon-extension/carte-tarifaire' ) ) {
wp_enqueue_script( 'carte-tarifaire-js' );
}
} );
Ce genre de garde-fou allège le nombre de requêtes HTTP sur les pages qui n’ont pas besoin du script, sans dupliquer la logique de détection à chaque nouvel appel de fonction.
Sur nos audits de performance, on retrouve encore régulièrement des expressions régulières maison pour détecter un bloc dans le contenu. Les remplacer par
has_block()prend quelques minutes et supprime une source de bugs difficile à reproduire.
En résumé
has_block() et parse_blocks() couvrent l’essentiel des besoins de détection côté serveur, sans jamais avoir à manipuler du texte brut. La première convient à un simple test conditionnel, la seconde à toute logique qui doit lire les attributs réels d’un bloc. Les deux fonctions font partie du cœur de WordPress et restent documentées sur developer.wordpress.org.