Le blog culinaire de l’Atelier Nomade voulait qu’une recette affiche une note globale, éditable directement depuis le bloc dans l’éditeur, sans passer par un champ ACF ni par un plugin d’avis. Le cas d’usage colle parfaitement à useEntityProp : la note appartient à l’article (le post), pas au bloc en particulier, et doit rester accessible même si le bloc est un jour supprimé et réinséré.
Cet article ne revient pas sur le fonctionnement théorique de useEntityProp, déjà détaillé ailleurs sur WP Moderne ; il montre le bloc complet, de l’enregistrement du champ meta à l’affichage sur le front, avec la validation qui manque souvent dans les exemples simplifiés.
Déclarer le champ meta côté PHP
Avant toute chose, le champ doit être exposé dans l’API REST et validé à l’écriture, faute de quoi n’importe quelle valeur transmise depuis l’éditeur (y compris hors plage) serait enregistrée telle quelle :
add_action( 'init', function () {
register_post_meta( 'recette', 'note_stellaire', [
'type' => 'integer',
'single' => true,
'default' => 0,
'show_in_rest' => true,
'auth_callback' => fn() => current_user_can( 'edit_posts' ),
'sanitize_callback' => function ( $valeur ) {
$valeur = (int) $valeur;
return max( 0, min( 5, $valeur ) );
},
] );
} );
Le sanitize_callback borne la valeur entre 0 et 5 quel que soit ce qui est envoyé, y compris depuis un appel REST direct qui contournerait l’interface du bloc.
Le composant d’édition
Le bloc lit et écrit ce champ via useEntityProp, avec un contrôle visuel en étoiles cliquables plutôt qu’un simple champ numérique :
import { useEntityProp } from '@wordpress/core-data';
function Edit() {
const [note, setNote] = useEntityProp('postType', 'recette', 'meta');
const noteActuelle = note?.note_stellaire ?? 0;
const definirNote = (valeur) => {
setNote({ ...note, note_stellaire: valeur });
};
return (
{[1, 2, 3, 4, 5].map((position) => (
))}
);
}

Notez l’usage de {...note, note_stellaire: valeur} plutôt qu’un objet minimal : le meta est un objet regroupant potentiellement d’autres champs (temps de préparation, difficulté), et l’écraser sans fusion effacerait les autres valeurs déjà enregistrées.
L’affichage sur le front
Le rendu public utilise un bloc dynamique classique, sans dépendre de React ni de useEntityProp, puisque le front n’a pas accès au store core-data de l’éditeur :
<?php
$note = (int) get_post_meta( get_the_ID(), 'note_stellaire', true );
?>
<div class="wp-block-atelier-note-stellaire" role="img" aria-label="Note de <?php echo esc_attr( $note ); ?> sur 5">
<?php for ( $i = 1; $i <= 5; $i++ ) : ?>
<span aria-hidden="true"><?php echo $i <= $note ? '★' : '☆'; ?></span>
<?php endfor; ?>
</div>
L’attribut role="img" avec un aria-label descriptif évite qu’un lecteur d’écran n’annonce cinq caractères étoile sans contexte.
Ce qu’on gagne par rapport à un attribut de bloc classique
- La note survit à une suppression et réinsertion du bloc, puisqu’elle vit dans le post, pas dans le contenu sérialisé du bloc.
- Elle reste accessible à d’autres blocs ou requêtes (un Query Loop triable par note, par exemple), ce qu’un attribut de bloc classique ne permet pas.
- Elle est modifiable via l’API REST par un script externe, utile pour une synchronisation avec un import de recettes en masse.
Dès qu’une donnée doit survivre au bloc qui l’affiche, elle n’a rien à faire dans les attributs du bloc.
Pour aller plus loin
Sur ce projet, la note stellaire alimente désormais un tri dans le Query Loop de la page « Nos meilleures recettes », simplement en interrogeant le meta note_stellaire via meta_key et orderby dans les paramètres de requête du bloc Query Loop, sans aucun code supplémentaire côté PHP.