Formation « Créer des blocs avec Gutenberg »

Le bloc « plugin » : utiliser Ajax pour se connecter à une API distante

Lecture : 5 minutes • 2

Dans la même lignée que le bloc Article, le bloc Plugin permet de récupérer les informations d’une extension à partir du site wordpress.org. On va donc étudier le code du bloc afin de voir comment cela fonctionne sous le capot.

Présentation du bloc

Voici un bloc dont je suis plutôt fier car il trouve son utilité dans de nombreux blogs, notamment ceux qui présentent des extensions WordPress.

Il permet de rechercher une extension dans le répertoire officiel wp.org et d’afficher le même type de bloc que l’on a lorsque l’on ajoute une extension dans l’interface d’administration, dans la rubrique Extensions :

Le bloc Plugin dans l'éditeur Gutenberg, accompagné d'un moteur de recherche.
Le bloc plugin et son moteur de recherche

Sympa non ? Et ce bloc ressemble énormément au bloc article, que l’on a abordé dans le cours précédent.

On va va trouver en substance la même logique, autant au niveau du bloc que du champ de recherche, à la différence près qu’au lieu de chercher sur l’API de notre site, on va sonder une API distante : wp.org.

Conseil

Avan de lire ce cours, je vous conseille d’avoir lu le précédent afin de bien comprendre tous les concepts.

Vous retrouverez le code de ce bloc dans le dossier src/20-plugin du plugin qui accompagne cette formation, disponible sur Github.

Au niveau des attributs, on n’en aura qu’un seul, du type string : on va enregistrer le slug du plugin, à la place d’un identifiant d’article.

JSON
20-plugin/block.json

Le composant SearchPlugin

Maintenant si on va faire un tour du côté de l’inspecteur, on peut voir que j’appelle le composant <SearchPlugin>, qui va assigner à notre attribut plugin le slug de l’extension qu’on aura choisi lors d’une recherche.

Et vous allez voir que sont fonctionnement ressemble beaucoup à celle du <SearchPost> du cours précédent.

JSX
20-plugin/inspector.js

Allons voir du côté du composant, dans /components/searchplugin/index.js. Cette fois, je ne vais pas utiliser l’API Rest de WordPress, car on va sonder une API distante. Et WordPress fournit une série de fonctions pour cela en PHP.

Ce que je vais faire à la place, c’est une requête Ajax vers une fonction PHP, qui s’occupera de lancer la requête vers wordpress.org.

JSX
components/searchplugin/index.js

D’ailleurs si vous souhaitez réviser vos bases en Ajax avec WordPress, je vous invite à consulter le cours dédié à ce sujet dans la formation développeur de thèmes :

Cours Ajax et WordPress

Cette fonction va appeler l’action capitainewp_search_plugins que l’on va retrouver dans notre PHP.

PHP
capitainewp-gut-bases.php

Ici, on va commencer par charger le fichier plugin-install.php du coeur de WordPress, car il n’est pas chargé automatiquement, et on en aura besoin pour accéder aux fonctionnalités de recherche d’extensions.

Justement, un peu après, on utilise la fonction plugins_api() qui permet de sonder le répertoire officiel des extensions de WordPress.

  • Le premier paramètre, query_plugins, permet d’indiquer qu’on va faire une recherche ;
  • Le second permet d’envoyer un tableau d’arguments, où l’on indique le nombre de résultats à afficher (20), la recherche, et les champs qu’on veut recevoir.

Si vous voulez en savoir plus sur cette fonction et ses paramètres, vous trouverez tous les détails dans la documentation.

Attention

La recherche d’extension est un peu capricieuse, il faut impérativement fournir un nom complet et exact. Les recherches approximatives ne donneront pas de résultat. Essayez depuis votre interface d’administration et vous constaterez le même souci.

Ensuite, pour chaque résultat, je vais trier les données reçues via la fonction capitainewp_prepare_plugins_data() pour ne garder que celles dont j’ai besoin. Elle sert notamment :

  • Décoder les entités HTML sur le titre et la description pour éviter les soucis d’encodage de caractères spéciaux ;
  • Récupérer l’icône de l’extension la plus adaptée (si la version 2x existe, je prend celle-ci, car plus grosse) ;
  • Optimiser le nombre d’installations actives pour avoir « 1+ millions installations actives » ou « moins de 10 installations actives » comme le fait WordPress dans l’admin ;
  • Enlever le lien de l’auteur (car leur balise a n’intègre pas de _blank) ;
  • Transformer la note sur 100 en une suite d’étoiles jaunes SVG pleines, semi pleines et vides.

Enfin, je renvoie le tout à JS via wp_send_json_success().

De retour dans mon JS, on peut voir que, comme pour le bloc Article du cours précédent, je stocke mes résultats dans une variable results, grâce à setResults, qui sont définis par le hook React useState.

Le bloc plugin

Dans block.js, on va également avoir une requête Ajax qui ciblera cette fois capitainewp_get_plugin(), que l’on retrouvera également dans mon fichier PHP.

Cette fonction est quasiment la même que l’autre à la différence que :

  • Cette fois on appellera plugin_information pour récupérer les informations de l’extension dont on fourni le slug (plus de recherche donc) ;
  • Et on n’obtiendra qu’un seul résultat, et non plus un tableau.
PHP
capitainewp-gut-bases.php

Côté JS, on utilise des hooks fort utiles :

  • Le hook useEffect permet de lancer automatiquement la fonction getPlugin() lorsque la valeur de slug change ;
  • Et le hook useState permet de mettre à jour le rendu du composant lorsque la valeur de plugin est modifiée.
JSX

Pour gérer le côté dynamique et asynchrone d’un composant, cette paire de hooks est vraiment pratique, voir même indispensable !

Aparté: Avant les hooks React

Avant ces hooks, introduits avec React 16.8, on procédait autrement. Si vous avez fait du React il y a longtemps, vous aviez peut-être utilisé des fonctions comme componentWillMount() et ComponentDidUpdate().

Mais aujourd’hui, tout passe par des hooks ! Ils sont faciles à reconnaitre car ils commencent toujours par le mot clé use.

Maintenant, si on regarde du côté du HTML généré pour ce bloc, on devrait avoir :

HTML

Il n’y a qu’un commentaire : il n’y aura pas de HTML enregistré en base. On va générer le markup de ce bloc en PHP au moment de l’affichage de la page où il sera affiché.

Le rendu en PHP

Comme d’habitude, lors de la déclaration du bloc en PHP, j’ai indiqué une fonction de callback qui servira au rendu du bloc en front.

PHP
capitainewp-gut.bases.php

C’est quasiment la même fonction que pour Javascript en réalité. La seule différence, c’est qu’au lieu de renvoyer du JSON, on va renvoyer du HTML prêt à l’emploi.

Information

Avec une approche hybride JS + PHP, parfois il est inévitable d’avoir des duplications de code.

Le template se trouve dans templates/plugin.php et ressemble comme deux gouttes d’eau au template JS :

PHP
templates/plugin.php

Et voilà, on a fait le tour. Essayez d’afficher une publication contenant votre bloc extension, et vous devriez le voir apparaitre !

Comme il est dynamique, il sera mis à jour automatiquement lorsque les données changeront sur wordpress.org.

Mais si vous avez un système de cache, il se peut que les informations ne soient pas directement à jour : il faudra attendre que le cache expire pour cela.

Mise en pratique : Vers d’autres API !

Maintenant que vous savez faire, plus aucune API ne vous résistera ! Alors pourquoi ne pas tenter d’aller sonder des API comme Unsplash ou encore Giphy, afin de permettre d’insérer facilement des photos ou des gifs animés dans vos publications ?

Un bloc permettant de lancer une recherche sur Unsplash
Un bloc Unsplash

Grâce aux API, tout un nouveau monde de possibilités s’offre à vous ! C’est ce que j’adore d’ailleurs avec le web.


Comme on a pu le voir dans ce cours et le précédent, lorsque l’on réalise un bloc dynamique, mieux vaut stocker uniquement l’identifiant de la ressource et récupérer ses informations au dernier moment. Cela permet de s’assurer que les données soient toujours à jour, même si pour cela il faut faire plusieurs requêtes API.

Dans le prochain cours on va voir comment créer des blocs encore plus facilement grâce aux champs ACF !

2

Questions, réponses et commentaires

  1. Adam Refined

    Le 25 août 2023

    D’abord, merci pour la 1453ᵉ fois pour tes cours. Je trouve ce chapitre très intéressant pour offrir une expérience utilisateur agréable pour la personne qui s’occupe du back end.

    On pourrait s’en servir pour intégrer facilement des icônes ou des fonts aussi non ? Par exemple Fontawesome ou Google fonts.

    1. Maxime BJ

      Le 25 août 2023

      Merci !
      Pour ça j’utiliserais plutôt les fonctions register script classiques de WP afin que le chargement soit global. Mais le bloc pourrait permettre de choisir une police ou une icône en effet. Tu pourrais charger conditionnellement les scripts en vérifiant que le bloc est bien présent dans la page avec le conditional tag has_block().

Laisser un commentaire