Quand on débute avec l’API des blocs, on a vite envie d’entasser toutes ses données dans un unique attribut de type string, quitte à parser soi-même le HTML plus tard. C’est une mauvaise idée : Gutenberg dispose d’un système d’attributs bien plus fin, capable d’extraire automatiquement une valeur depuis le balisage sauvegardé, sans qu’on ait à écrire la moindre ligne de parsing.
Cet article détaille chaque source d’attribut disponible dans registerBlockType : html, attribute, query, text (une variante d’html peu documentée), et meta pour lier un attribut à un champ personnalisé. On verra aussi pourquoi le choix du type et de la valeur par défaut n’est jamais un détail anodin.
Comment fonctionne le sourcing d’attributs
Quand vous déclarez un bloc, chaque entrée de l’objet attributes peut préciser une source. Sans source, Gutenberg stocke la valeur directement dans le commentaire HTML délimiteur du bloc (par exemple <!-- wp:wpmoderne/citation {"auteur":"Victor Hugo"} /-->). Avec une source, en revanche, la valeur est extraite du HTML sauvegardé par save(), au moment où l’article est rechargé dans l’éditeur.
Cette distinction change tout : un attribut sans source vit dans les métadonnées JSON du commentaire de bloc (invisible en front-end classique), tandis qu’un attribut avec source vit dans le balisage HTML lui-même, ce qui le rend lisible même si l’on affiche l’article sans passer par WordPress.
La source « html » : le cas le plus courant
C’est la source que l’on utilise pour tout contenu texte enrichi (avec du gras, des liens, etc.), généralement de pair avec le composant RichText. Elle prend une option selector qui cible l’élément dont on veut récupérer le innerHTML.
attributes: {
citation: {
type: 'string',
source: 'html',
selector: 'blockquote',
},
auteur: {
type: 'string',
source: 'html',
selector: 'cite',
default: '',
},
},

Dans save(), il faut impérativement que le HTML produit contienne bien un <blockquote> et un <cite>, faute de quoi l’extraction échouera silencieusement et l’attribut reviendra à sa valeur par défaut à la réouverture. C’est l’un des pièges les plus fréquents : modifier la structure de save() sans mettre à jour le selector correspondant.
La source « attribute » : cibler un attribut HTML précis
Utile quand la donnée n’est pas du texte mais la valeur d’un attribut HTML — une URL d’image, un alt, une classe CSS. On combine selector et attribute :
attributes: {
url: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src',
},
alt: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'alt',
default: '',
},
},
C’est exactement la mécanique employée par le bloc Image natif pour récupérer l’URL et le texte alternatif depuis la balise <img> sauvegardée. Sans cette source, il faudrait dupliquer l’URL dans les métadonnées JSON du bloc en plus du HTML, ce qui crée deux sources de vérité désynchronisables.
La source « query » : extraire une liste d’éléments
Quand un bloc contient plusieurs occurrences d’un même sous-élément — les images d’une galerie, les lignes d’une liste —, la source query permet de récupérer un tableau d’objets, chacun construit à partir d’un sous-ensemble de sources.
attributes: {
images: {
type: 'array',
source: 'query',
selector: 'figure',
query: {
url: {
type: 'string',
source: 'attribute',
selector: 'img',
attribute: 'src',
},
legende: {
type: 'string',
source: 'html',
selector: 'figcaption',
},
},
default: [],
},
},
Le selector de premier niveau cible chaque bloc répété (ici, chaque <figure>), et l’objet query décrit, pour chacun, comment extraire ses propres sous-valeurs. C’est la technique qu’utilise en interne le bloc Galerie natif.
La source « meta » : lier un attribut à un champ personnalisé
Contrairement aux précédentes, la source meta ne lit rien dans le HTML du bloc : elle relie l’attribut à un champ personnalisé (post meta) de l’article, enregistré côté PHP avec register_meta(). C’est pratique pour partager une donnée entre plusieurs blocs, ou pour la rendre accessible à un thème classique en dehors du contenu du bloc.
<?php
function wpmoderne_register_meta() {
register_post_meta( 'post', 'wpmoderne_note_lecture', array(
'show_in_rest' => true,
'single' => true,
'type' => 'string',
'default' => '',
) );
}
add_action( 'init', 'wpmoderne_register_meta' );
attributes: {
noteLecture: {
type: 'string',
source: 'meta',
meta: 'wpmoderne_note_lecture',
},
},
Attention : pour que le bloc puisse lire et écrire ce champ, il faut aussi que le composant appelle withSelect/withDispatch (ou le hook useSelect/useDispatch côté @wordpress/data) pour synchroniser l’attribut avec les métadonnées de l’article, l’attribut source: meta seul ne suffisant pas à créer cette liaison bidirectionnelle dans l’éditeur.
Sans source : le stockage dans le commentaire de bloc
Pour tout ce qui relève d’un réglage d’interface — une couleur choisie dans un menu déroulant, une case à cocher, un nombre de colonnes —, on omet simplement source. La valeur part directement dans le JSON du commentaire délimiteur :
attributes: {
colonnes: {
type: 'number',
default: 3,
},
alignementCentre: {
type: 'boolean',
default: false,
},
},
Bien choisir le type et la valeur par défaut
Le champ type suit le vocabulaire JSON Schema : string, number, boolean, array, object. Gutenberg s’en sert pour valider et caster la valeur extraite. Un piège classique : déclarer type: 'number' pour un attribut sourcé en attribute depuis un data-*, alors que tous les attributs HTML sont des chaînes de caractères — sans coercition explicite, on récupère parfois une chaîne là où l’on attend un nombre.
Quant à default, elle n’est utilisée que lorsque la source ne trouve rien à extraire (bloc fraîchement inséré, ou sélecteur introuvable). Ne comptez jamais sur elle pour « réinitialiser » un attribut existant : une fois que du HTML valide est présent, la valeur par défaut est ignorée au profit de la valeur extraite.
| Source | Origine de la donnée | Cas d’usage typique |
|---|---|---|
| Aucune | JSON du commentaire de bloc | Réglages d’interface (couleur, nombre, booléen) |
html | innerHTML d’un élément | Texte enrichi avec RichText |
attribute | Valeur d’un attribut HTML | URL d’image, texte alternatif, classe CSS |
query | Liste d’objets extraits par répétition | Galerie d’images, liste de témoignages |
meta | Champ personnalisé de l’article | Donnée partagée entre plusieurs blocs |
Testez toujours vos sources d’attributs en rechargeant la page après publication, pas seulement en prévisualisation : certaines erreurs d’extraction ne se révèlent qu’au passage par le HTML réellement enregistré en base.
En résumé
Le choix d’une source d’attribut n’est jamais neutre : il détermine où vit la donnée (JSON du bloc, HTML sauvegardé, ou métadonnées de l’article), comment elle survit à une modification manuelle du contenu, et si elle reste lisible en dehors de l’éditeur. Une bonne règle de départ : utilisez html et attribute pour tout ce qui doit rester visible dans le balisage final, réservez l’absence de source aux réglages purement éditoriaux, et n’utilisez meta que lorsque la donnée doit vraiment vivre au niveau de l’article plutôt qu’au niveau du bloc.