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

Blocs Gutenberg

has_block() et parse_blocks() détectent un bloc côté PHP sans regex

Chercher une chaîne comme wp:core/gallery dans le contenu brut fonctionne, jusqu'au jour où un attribut casse la détection. Deux fonctions natives évitent ce piège.

Par WordPress Développement • 20 mai 2020 • 4 min de lecture • Aucun commentaire
has_block() et parse_blocks() détectent un bloc côté PHP sans regex

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

L'essentiel à retenir : has_block() teste la présence d'un bloc sans analyser le HTML ; parse_blocks() retourne une structure exploitable ; Fonctionne aussi sur les blocs imbriqués et réutilisables

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 son ref et 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 simple strpos().

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.

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