# Une note stellaire stockée en post meta avec useEntityProp

> Bloc complet de notation par étoiles pour une fiche recette, avec validation d'entrée et affichage front, au-delà de la théorie déjà publiée sur useEntityProp.

- Auteur : Clément Hadrot
- Publié le : 2024-06-06
- Mis à jour le : 2024-06-06
- Catégorie : Blocs Gutenberg
- URL : https://wpmoderne.dev.wordpress-developpement.fr/blocs/note-stellaire-post-meta-useentityprop/

## L’essentiel

- register_post_meta expose la note en REST
- useEntityProp lit et écrit sans passer par les attributs de bloc
- Validation côté PHP indispensable avant enregistrement

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) => (
        
          {position
```

> L'essentiel à retenir : register_post_meta expose la note en REST ; useEntityProp lit et écrit sans passer par les attributs de bloc ; Validation côté PHP indispensable avant enregistrement

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.
