Formation « Créer des blocs avec Gutenberg »

Bloc dynamique via l’API REST et rendu en PHP

Lecture : 5 minutes • 0

Dans ce cours on va voir comment réaliser un bloc dynamique qui va afficher par exemple la liste toujours à jour des 3 derniers articles publiés.

On va maintenant monter le niveau d’un cran avec la création d’un bloc qui affiche les 3 derniers articles en date. On parle alors de blocs dynamiques.

On emploie ce terme car le contenu n’est pas écrit directement en dur dans le HTML, comme il est susceptible de changer avec le temps.

L’exemple que l’on va voir dans ce cours servira de base pour créer à terme d’autres types de blocs, comme l’aperçu d’un article ou d’un produit WooCommerce choisis par l’utilisateur.

Le bloc que l’on va voir est en apparence tout simple :

Bloc dynamique Gutenberg

Avec un écran de chargement, le temps de récupérer les informations via l’API :

Chargement d'un bloc dynamique

On va prendre pour cet exemple le fichier src/15-dynamic.

À terme, on pourrait même créer des blocs plus poussés comme celui-ci, où l’on peut choisir son article plutôt que de prendre automatiquement le plus récent :

Utiliser WithSelect pour contacter l’API Rest

On va commencer par charger un nouveau composant appelé withSelect directement dans notre index.js :

JS
src/15-dynamic/edit.js

C’est une méthode qui se situe en amont de notre bloc et va notamment nous permettre de faire une requête vers l’API REST pour réceptionner notre contenu dynamique, ici les 3 derniers articles en date.

En fait, withSelect permet pleins de choses. C’est ici que l’on peut accéder à l’API Datade Gutenberg, c’est à dire l’entrepôt où toutes les données sont stockées. On pourrait y récupérer par exemple la liste de tous les autres blocs actuellement présents dans l’article. Je l’ai utilisé pour Advanced Gutenberg Blocks pour gérer mon sommaire automatique.

Voyons maintenant ce qu’il se passe dans WithSelect :

JSX
src/14-dynamic/index.js

On remarque qu’au lieu de lancer Edit tout de suite, on lance directement la fonction withSelect(), et on utilise select() qui va nous permettre de piocher dans les entités de données de Gutenberg.

Et on le fait de cette manière : 

JSX

La fonction getEntityRecords() nous permet d’aller chercher des informations en base, ici on indique que l’on veut filtrer par type de publication et on choisit Posts, et dans les paramètres complémentaires on indique que l’on en veut que 3. Cette donnée est ensuite renvoyée via le return().

C’est là où ça se gâte :  tout de suite après cette fonction on enchaine avec des parenthèses collées à une autre fonction.

C’est dans cette deuxième fonction que l’on va faire comme d’habitude, à savoir appeler Edit. par contre, il y aura une petite différence : dans les props renvoyées, il y aura une nouvelle donnée appelée posts.

JSX
src/15-dynamic/edit.js

En résumé, WithSelect vient se greffer en amont de notre Edit pour récupérer une donnée dans l’API, et la transmettre à notre bloc.

Cas de figures selon les résultats renvoyés

Du coup désormais on se confronte à 3 cas de figure différents dans notre Edit :

  1. L’API n’a encore rien renvoyé ;
  2. L’API a renvoyé aucun résultat ;
  3. L’API a renvoyé une liste d’articles.

Comme dans le cas d’une requête AJAX asynchrone, les résultats n’arrivent pas tout de suite, d’où l’utilité de mettre un écran de chargement même si c’est pour un bref instant (moins d’une seconde en général).

Et comme je vous ai dit c’est React qui gère le cycle de vie du composant. Du coup quand l’API aura répondu, React raffraichira l’affichage en prenant en compte les nouvelles données automatiquement. Rien besoin de faire de notre côté.

Au niveau du code, au lieu d’utiliser les ternaires dans le return(), je vais cette fois faire 3 returns différents, en fonction des cas :

JSX
src/15-dynamic/edit.js

Je me permet cette approche car dans chaque cas le rendu sera complètement différent (et donc pas de répétition en vue).

Dans le cas où je n’ai pas encore eu de réponse de l’API, j’affiche le <Spinner /> qui est une roue animée pour faire patienter, et un texte « chargement » dans un bloc gris avec un petit peu de CSS.

Si je n’ai pas de résultat, j’affiche le même bloc gris avec la mention « Aucun article trouvé ». Et enfin si tout va bien j’affiche ma liste d’articles.

D’ailleurs j’en profite pour utiliser la fonction map() en JS, qui, comme on a déjà pu le voir, est une sorte de forEach qui affiche le résultat dans le template.

Enfin, vous remarquez que j’ai un code simple, qui ne nécessite pas de if/else ou de tests à rallonge : si une condition est vraie, le « return » renvoie le HTML et la fonction arrête à ce moment son exécution. Elle ne va donc pas plus loin.

Une fonction save minimaliste

Le plus gros lifting est la méthode save, qui ne renvoie plus rien du tout ! C’est logique puisque notre composant est dynamique : on ne peut donc pas enregistrer un HTML. Sinon côté front on n’aurait pas réellement les 3 derniers articles, mais les 3 articles les plus récents au moment où l’article a été publié.

JSX
src/15-dynamic/save.js

Du coup c’est en PHP que l’on va s’occuper d’afficher ce bloc !

La seule chose enregistrée par l’éditeur sera le commentaire HTML :

HTML

A l’avenir on pourra toujours y passer des attributs, notamment dans le cas où par exemple l’utilisateur peut sélectionner les articles qu’il souhaite afficher (et pas forcément les 3 derniers). Les identifiants de ces articles seraient donc stockés dans un attribut affiché dans ce commentaire. J’ai un exemple comme celui-ci que je vous montrerais lorsque l’on verra les études de cas.

Le rendu en PHP

On va donc aller faire un tour du côté de PHP. J’ai mis mon code dans capitainewp-gut-bases.php.

PHP
capitainewp-gut-bases.php

On utilise la fonction register_block_type() en PHP cette fois pour indiquer quelle fonction lancer quand WordPress tombe sur un bloc dynamique.

Il faut indiquer en premier paramètre le nom du bloc, ici capitainewp/dynamic, puis ensuite la fonction de callback.

J’ai préalablement vérifié que la fonction register_block_type() existait, ce qui revient à dire que l’on vérifie que Gutenberg est bien installé (via le plugin, ou nativement dans WordPress).

C’est un test utile que l’on peut garder même après la sortie de l’éditeur pour des questions de rétrocompatibilité.

Dans ma fonction de callback capitainewp_dynamic_render() je n’ai plus qu’à récupérer mon contenu via la fonction get_posts() et générer le markup correspondant.

Information

Comprenez bien que côté front-end, il n’y a pas de React, d’appel API, ou quoi que ce soit d’asynchrone en JS, on fait un simple get_posts() en PHP qui récupère les articles voulus, à la manière d’une WP_Query.

Petite astuce : au lieu d’utiliser une variable $markup et de concatener du HTML, vous pouvez utiliser les fonctions ob (ob_start, ob_end_flush, ob_get_contents…) pour écrire le rendu.

Pourquoi donc ? Car ici vous ne pouvez pas directement afficher du HTML (en mode echo), il faut le retourner via un return().

Attention

Le code PHP pour récupérer des articles fait doublon avec ce que l’on a déjà fait en JS. Malheureusement on n’a pas d’autres alternatives que d’écrire 2 fois la même logique dans deux languages différents.


Voilà ! Vous savez désormais faire un composant qui est capable de récupérer des données dynamiquement. Cela vous ouvrira pas mal de portes pour la suite !

Dans le prochain cours, on va voir comment on peut permettre d’insérer des blocs enfants à l’intérieur de notre bloc grâce au composant InnerBlocks.

0

Questions, réponses et commentaires

Laisser un commentaire