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

Blocs Gutenberg

render_block_context transmet une donnée du parent à ses blocs enfants

« Undefined array key » dans le rendu d'un bloc enfant qui attend une donnée du parent : le filtre render_block_context règle ce partage sans props JavaScript à faire remonter.

Par WordPress Développement • 7 octobre 2023 • 4 min de lecture • Aucun commentaire
render_block_context transmet une donnée du parent à ses blocs enfants

« Undefined array key « unite » » dans le fichier render.php d’un bloc enfant : symptôme classique d’un contexte de bloc mal transmis. Le bloc enfant a bien déclaré "usesContext": ["mon-agence/unite"] dans son block.json, mais la valeur attendue n’arrive jamais jusqu’à son rendu PHP, parce que le parent ne l’a jamais réellement fournie.

Le contexte de bloc (context et providesContext dans block.json) fonctionne très bien pour des valeurs statiques définies une fois pour toutes par le parent. Il devient plus délicat dès que la valeur à transmettre dépend d’un calcul effectué côté PHP au moment du rendu, par exemple une devise déduite d’un réglage global ou d’une donnée liée à l’article courant. C’est exactement le cas que couvre le filtre render_block_context.

Le problème concret

Un bloc parent « Grille de prix » propose plusieurs blocs enfants « Ligne de prix », chacun devant afficher un montant dans l’unité monétaire définie globalement pour le site (une donnée stockée dans une option, pas dans un attribut de bloc). Déclarer cette unité comme providesContext statique dans le parent obligerait à dupliquer un attribut inutile sur chaque instance du bloc parent, alors que la valeur réelle vient d’ailleurs et peut changer sans que l’article ne soit modifié.

La solution avec render_block_context

add_filter( 'render_block_context', function ( $context, $parsed_block ) {
	if ( ( $parsed_block['blockName'] ?? '' ) !== 'mon-agence/grille-de-prix' ) {
		return $context;
	}

	$context['mon-agence/unite'] = get_option( 'mon_agence_devise', 'EUR' );

	return $context;
}, 10, 2 );

Ce filtre s’exécute côté PHP, juste avant le rendu de chaque bloc, avec accès au contexte déjà accumulé et au bloc parsé courant. Il permet d’injecter une valeur calculée dynamiquement dans le contexte transmis aux enfants, exactement comme si le parent l’avait déclarée statiquement, mais sans jamais la stocker en tant qu’attribut sérialisé dans le contenu de l’article.

L'essentiel à retenir : Complète le contexte déclaré côté JavaScript par usesContext ; S'exécute côté PHP, au moment du rendu final ; Utile pour une donnée calculée dynamiquement, pas seulement statique

Ce qui doit rester déclaré côté JavaScript

Le filtre PHP ne dispense pas de la déclaration classique dans les deux fichiers block.json : le parent doit toujours lister "providesContext": { "mon-agence/unite": "uniteMonetaire" }, même si la valeur réelle n’existe qu’en PHP, et l’enfant doit toujours déclarer "usesContext": ["mon-agence/unite"]. Sans ces déclarations, le mécanisme de contexte ne sait tout simplement pas qu’une donnée doit circuler entre ces deux blocs, et le filtre PHP n’aurait rien à compléter.

  • Déclaration du contexte dans les deux block.json : obligatoire, encadre quelles clés peuvent circuler.
  • Valeur statique connue à l’avance : un simple attribut suffit, pas besoin du filtre.
  • Valeur calculée au moment du rendu, indépendante du contenu de l’article : render_block_context est la bonne option.

Variantes de cette recette

Contexte dépendant de l’article courant

add_filter( 'render_block_context', function ( $context, $parsed_block ) {
	if ( ( $parsed_block['blockName'] ?? '' ) === 'mon-agence/fiche-produit' ) {
		$context['mon-agence/enPromotion'] = (bool) get_post_meta(
			get_the_ID(),
			'en_promotion',
			true
		);
	}

	return $context;
}, 10, 2 );

Contexte conditionné à un rôle utilisateur

Le même filtre permet aussi de transmettre une information liée à l’utilisateur courant (par exemple, afficher un tarif différent selon que le visiteur est connecté), en s’appuyant sur is_user_logged_in() ou current_user_can() plutôt que sur une donnée figée dans le contenu.

Limites à connaître

Ce filtre agit au niveau du rendu final, pas dans l’éditeur : un bloc enfant qui a besoin d’afficher la même donnée pendant l’édition doit la récupérer autrement côté JavaScript (via useSelect sur une donnée équivalente, ou un attribut classique). Le contexte injecté par render_block_context ne remonte pas dans l’inspecteur de l’éditeur : il ne concerne que la sortie HTML générée pour le visiteur du site.

En résumé

render_block_context complète, côté PHP, ce que la déclaration statique de contexte dans block.json ne peut pas couvrir : les valeurs calculées au moment du rendu. Combiné à une déclaration correcte de providesContext et usesContext, ce filtre évite de dupliquer des attributs sur chaque bloc enfant pour une donnée qui, en réalité, appartient à un niveau plus global du site.

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