WP 5.2 et son nouveau hook pour les thèmes : wp_body_open

WP 5.2 et son nouveau hook pour les thèmes : wp_body_open

WordPress 5.2 introduit une nouvelle fonction wp_body_open() utilisée pour déclencher la nouvelle action wp_body_open. Cette action va permettre aux développeurs d’injecter du code immédiatement après la balise d’ouverture <body>.

Les thèmes sont encouragés à utiliser ce hook dès maintenant. La fonction doit être placée juste à l’intérieur de la balise d’ouverture <body> du fichier de template header.php.

Par exemple:

<body <?php echo body_class(); ?>
<?php wp_body_open (); ?>

L’utilisation de ce hook doit être réservée à la sortie d’éléments invisibles tels que les balises <script> ou des métadonnées supplémentaires. Il ne doit pas être utilisé pour ajouter du contenu HTML arbitraire à une page qui pourrait briser les mises en page ou conduire à des situations inattendues.

Retro Compatibility

Afin de prendre en charge les versions précédentes de WordPress, il est recommandé d’utiliser une astuce dans votre thème pour éviter l’erreur fatale PHP de la fonction non définie.

<?php
if ( ! function_exists ( 'wp_body_open' ) ) {
    fonction wp_body_open () {
        do_action ('wp_body_open');
    }
}

Notez que si votre thème doit être dans le dépôt officiel de thèmes, vous ne pourrez pas utiliser le préfixe wp_, car il sera taggué par le thème check (quelle ironie non ?).

Une alternative consiste à appeler directement do_action là où la fonction wp_body_open() est placée dans le premier exemple, comme ceci :

<?php
if ( function_exists( 'wp_body_open' ) ) {
    wp_body_open();
} else {
    do_action( 'wp_body_open' );
}

Les extensions peuvent détecter l’utilisation de cette fonction dans un thème en appelant did_action( 'wp_body_open' ); et en recourant à des méthodes alternatives si l’action n’a pas été déclenchée.

Source de ce début d’article, adapté par mes soins : https://make.wordpress.org/core/2019/04/24/miscellaneous-developer-updates-in-5-2/

Voici une capture de ce que ça donne dans un thème enfant de Twentynineteen, fichier header.php retouché :

 

Forward Compatibility

Alors c’est bien beau, mais ça force à créer un thème enfant (quoi, vous n’en aviez pas encore ?), ou modifier votre thème enfant (on ne modifie pas le thème parent hein !) et donc de toucher le code.

Même si c’est « simple », tout le monde n’a pas envie de devoir ouvrir via FTP (effe thé quoi ? feuteupeu ?) un fichier pour retoucher le code.

Cela n’est à faire que si vous avez créé votre propre thème maison, qu’il soit ou non sur le dépôt de WordPress.org.

Mais alors, est-il possible d’avoir le même comportement que la nouvelle fonction, dans les nouveaux thème ou thèmes à jour SANS retoucher le code !

N’existe-t-il pas une parade, un code magique qui permette de réussir à avoir ça pour les personnes ne souhaitant pas toucher le code !?

Hassan Cehef

J’ai fait ça pour vous en mode défi, j’ai souhaité le faire avec le code le plus court et propre possible, voici ce morceau magique :

add_action( 'get_header', 'baw_wp_body_open_buffer' );
function baw_wp_body_open_buffer() {
	ob_start();
	do_action( 'wp_body_open' );
	$wp_body_open_content = ob_get_clean();

	ob_start( function( $buffer ) use( $wp_body_open_content ) {
		return preg_replace( '(<body.*>)', "$0\n$wp_body_open_content", $buffer );
	} );
}

Ce code est à placer dans un fichier php (nom de votre choix) et à uploader dans /wp-content/mu-plugins/, dossier à créer s’il n’existe pas.

Attention, si le thème gère déjà la fonction au bon endroit, ce code est un doublon ! Supprimez alors ce fichier (ou ne l’uploadez pas ! haha). Non, je ne peux pas juste vérifier si la function_exists, cela ne suffit pas à savoir si le thème l’utilise. Et le did_action ? Je le saurais quand il sera trop tard. La solution serait d’aller lire le contenu du fichier header.php et de détecter si le nom de la fonction est présente, mais comme ça le ferait à chaque chargement de page, je trouve ça trop lourd.

Quelques explications sur le code

Ligne par ligne, je vous explique mes choix et comment on arrive au résultat. Attention/disclaimer : le mieux est d’éditer le code du thème !

1. add_action( 'get_header', 'baw_wp_body_open_buffer' );

Je me cale sur l’action get_header qui est un hook lancé par WordPress lors de l’inclusion du fichier header.php, c’est ce fichier qui, théoriquement, contient la balise <body> et donc doit contenir la fonction wp_open_body().

2. function baw_wp_body_open_buffer() {`

C’est juste le nom de ma callback, je commence avec baw pour BoiteAWeb, vous le saviez non ?

3. ob_start();

Allez, je commence par ouvrir une mémoire tampon (ob = Output Buffer), tout ce qui va vouloir s’afficher (echo, print, printf, HEREDOC, fermeture de balise PHP, etc) va se mettre en mémoire tampon à la place.

4. do_action( 'wp_body_open' );

C’est maintenant que j’utilise le nouveau code de WordPress. Théoriquement vous souhaitez afficher une balise <script>, c’est pour ça qu’elle a été faite. Mais au lieu de s’afficher, hop, en tampon !

5. $wp_body_open_content = ob_get_clean();

Ici je retourne le contenu du tampon de sortie dans la variable $wp_body_open_content puis l’efface et enfin coupe le tampon, tout est fait par ob_get_clean().

6.

Oui j’en parle de la ligne vide, faite respirer votre code !

7. ob_start( function( $buffer ) use( $wp_body_open_content ) {

Allez on complique un peu. Je relance une mémoire tampon mais cette fois avec en paramètre une fonction anonyme. La variable $buffer est le contenu de ce qui va être mis en mémoire tampon, il est donc passé en paramètre de ma fonction. J’ai aussi besoin du contenu du hook, je vais donc devoir faire un use(), sans ça et sans fonction anonyme j’aurais dû utiliser une variable globale, bof.

8. return preg_replace( '(<body.*>)', "$0\n$wp_body_open_content", $buffer );

C’est le code de ma fonction anonyme ici, une ligne suffit, je retourne un remplacement d’une expression régulière simple, je prends la balise <body> avec tout ce qu’elle peut contenir ou pas (.*), et je remplace par le contenu de ce que le hook devait imprimer, le tout en gardant la balise <body> devant et en ajoutant un passage à la ligne pour faire propre avec \n. Le tout entre double quote pour évaluer les variables et ne rien concaténer.

9.     } );

Fermeture de la fonction de callback anonyme et du ob_start() en même temps.
10. }

Fermeture de la fonction de callback du hook get_header.

Et voilà, vous avez un thème compatible 5.2 sans avoir touché le code. Bravo 😉

Vous aimez ? Partagez !


Réagir à cet article

220 caractères maximum