Étude de cas : les blocs de Advanced Gutenberg Blocks - Formation Gutenberg - Capitaine WP

Formation « Créer des blocs avec Gutenberg »

Étude de cas : les blocs de Advanced Gutenberg Blocks

Lecture :8 minutes •0

Rien de mieux que de s’essayer sur ses propres blocs afin d’évoluer. C’est ce que j’ai fait avec mon extension Advanced Gutenberg Blocks, et j’ai beaucoup appris. On va en profiter pour étudier tout cela et voir quelques blocs avancés en situation.

Avec nos compétences actuelles, on peut presque imaginer créer n’importe quel type de bloc ! J’en ai créé une dizaine avec Advanced Gutenberg blocks (très original comme nom…), et décidé de publier l’extension sur le répertoire officiel WordPress.

Voici une vidéo des blocs en action :

On retrouve des blocs pour afficher des articles, produits, un bouton d’achat, des extensions, un lien vers un autre site…

Je vous propose de la télécharger afin de tester les blocs en vrai :

Télécharger Advanced Gutenberg Blocks

Tour d’horizon de l’extension

On va regarder un peu comment est organisée l’extension, et ce qu’elle propose.

Attention

Cette extension a été écrite avec les anciens standards Gutenberg. Certains codes seront donc obsolètes. D’ailleurs, certaines options que je présente sont désormais disponibles nativement dans le coeur de Gutenberg et sont donc inutiles.

Une fois activée, vous verrez un nouveau menu Blocks :

Le tableau de bord des blocs AGB

J’ai créé une page de réglages dans laquelle je liste tous mes blocs, ainsi que tous ceux de Gutenberg. A noter qu’à l’heure où j’écris ces lignes, comme il n’y a pas de fonction en PHP pour lister les blocs, j’ai du en faire l’inventaire à la main. C’est du au fait que les blocs sont entièrement créés à partir de JS.

Désactivation des blocs

D’ici vous pouvez désactiver ceux qui ne sont pas nécessaires, afin d’alléger l’interface de Gutenberg. Un simple bouton « désactiver » ajoutera le nom du bloc dans une liste enregistée dans wp_options.

Au chargement de Gutenberg, je vais utiliser en JS la fonction wp.blocks.unregisterBlockType('block/name') pour désactiver les blocs indésirables. Vous pouvez voir le code en action dans dist/deactivator.build.js.

La liste de ces blocs est transmise de PHP vers JS via la fonction wp_localize_script()dans classes/WP/Gutenberg.php (ligne 75 environ), quand je suis dans le hook enqueue_block_editor_assets que l’on a vu dans le cours sur comment charger les ressources JS / CSS dans Gutenberg.

Options des blocs

Je vais aussi pouvoir mettre ici des options pour chaque bloc. Ce ne sont pas les réglages que l’on trouve dans l’inspecteur, ce sont des réglages plus durables.

Imaginez le bloc Google Map dans lequel je dois fournir la clé d’API. Je ne vais pas mettre un champ dans l’inspecteur, sinon l’utilisateur devra l’indiquer à chaque fois. Pas très pratique !

Bon en vrai, on pourrait enregistrer une valeur de l’inspecteur dans les custom fields. La valeur serait donc préchargée à chaque fois. Mais ça me dérange de « montrer » cette donnée dans l’inspecteur à chaque fois. Elle n’a pas sa place, surtout si vous êtes une agence qui fait un site pour un client.

J’ai donc fait des options pour chaque bloc, pour gérer ce type de cas.

C’est la même chose pour les blocs pubs : c’est dans ces options qu’il faudra venir insérer le code JS pour afficher la publicité, une bonne fois pour toutes.

Ce tableau de bord est créé classiquement avec les fonctions habituelles de WordPress comme add_menu_page()et register_setting().

J’y ai apporté mon CSS personnalisé car les pages d’options de WordPress proposées par défaut ne sont pas très sexy.

J’ai aussi ajouté un peu d’Ajax pour activer/ désactiver un bloc sans que cela recharge complètement la page.

Les blocs

Du côté de l’édition d’une page ou d’un article, vous trouverez les blocs et leurs options :

Les réglages du bloc

J’ai eu quelques défis techniques à relever lors de la création de mes blocs, dont :

  • Les blocs produit / article qui doivent utiliser l’API Rest WordPress pour récupérer les informations nécessaires
  • Le bloc Google Map qui doit manipuler une librairie JS non react (la GMap API)
  • Le bloc Plugin qui doit faire une requête sur wp.org pour récupérer la liste des extensions (heureusement qu’il y a une API Rest pour cela)
  • Le bloc Aperçu de site qui doit récupérer sur les sites distants les informations Open Graph (og:title, og:description, og:image…)

On va voir certains de ces blocs plus en détails dans les cours suivants.

J’ai également du créer des composants React réutilisables. C’est le cas par exemple pour la recherche d’articles, d’adresse postale, et de produits : j’ai du créer un composant recherche qui permet d’indiquer un mot clé , et d’obtenir une liste de résultats.

Un composant recherche
Composant recherche

Le code des composants « recherche » se trouvent dans src/components/ mais on va y revenir.

On va maintenant aller voir comment est organisé le code de l’extension.

Organisation du code

Pour analyser le code, on va se rendre sur mon répertoire Github car dans l’extension, les fichiers sont compilés et donc illisibles. Voici le lien vers le projet :

Code source du projet

Si vous êtes curieux, j’ai détaillé la structure de mon extension ci-dessous, afin de montrer comment on peut organiser un plugin lorsque le code devient conséquent. Si vous préférez rester 100% Gutenberg, sachez juste que vous trouverez le code des blocks dans src/blocks/.

Architecture du code

Vous devriez reconnaitre certains aspects de l’arborescence puisque j’ai utilisé create-guten-blocks pour la base de mon extension.

Voici un résumé de l’organisation des fichiers :

Classes

le dossier classes contient tout le PHP de mon application. Tout ce qui est en rapport avec WordPress, comme les hooks, les déclarations de menus, options, se trouve dans classes/WP.

Comme les blocs ne sont pas déclarés en PHP, j’ai du le faire à la main, et pour cela j’ai créé le dossier classes/Blocks dans lequel j’ai un fichier par bloc.

Src

Le dossier src contient tout le code JS des blocs, j’ai créé deux sous-dossiers : src/blocks et src/components. Ce deuxième me permet d’y stocker des composants génériques réutilisables.

C’est notamment le cas du composant SearchPost, qui permet de chercher un article, une page, ou tout autre Custom Post Type.

Dans la même lignée SearchProduct permet de rechercher spécifiquement un produit WooCommerce et renvoie les données produits comme le prix.

Ce composant est utilisé par le bloc Produit, mais également par le bloc button Ajouter au panier.

Dist

Dist, comme on a déjà pu le voir au cours de cette formation, est le dossier dans lequel sont stockés les scripts relatifs à Gutenberg, et générés par Webpack et Babel.

Admin / Public

Ces deux dossiers permettent de stocker les autres ressources de type images, styles et scripts ainsi que les templates PHP pour l’admin et le front.

Dans le dossier admin on retrouvera les fichiers permettant la mise en page de ma page option, et de tout ce qui se trouverait dans l’interface d’administration (hors Gutenberg). Dans admin/templates par exemple on va retrouver le HTML de la page de réglages.

J’aime bien séparer la logique métier (le code PHP) du rendu HTML. Le code pour la page d’options se trouve dans classes/WP/Settings.php et le rendu dans admin/templates/settings.php.

Du côté de public on va trouver tout ce qui est destiné à être affiché sur la partie publique du site.

Pour le moment on va seulement retrouver les templates PHP pour afficher le code de certains blocs dynamiques comme le bloc Article, la Google Map ou le bouton ajouter au panier.

Dev

En plus de create-guten-blocks, j’ai ajouté Gulp pour compiler mes fichiers CSS destinés à la réalisation de la page settings.

Ce n’est pas idéal car ça m’oblige à utiliser 2 outils, Webpack et Gulp. Je pense optimiser cela à terme. Mais pour des besoins de simplicité, ça me suffit très bien pour le moment.

Programmation orientée objet

J’utilise la POO dans cette extension pour plusieurs raisons. Beaucoup ne l’utilisent pas avec WordPress car en réalité une programmation classique et l’utilisation de hooks suffit amplement.

L’objet ici n’apporte qu’une chose : pouvoir « sécuriser » les noms de fonctions. Au lieu mettre le slug du plugin en début de nom de fonction, je créé des objets PHP et j’ai une classe principale qui se trouve dans classes/AdvancedGutenbergBlocks.php. Elle est initialisée dans plugin.php.

PHP

J’ai donc là qu’une seule variable exposée à l’extérieur. De cette manière j’évite toute possibilité de conflits de noms de variables, de fonctions.

Pour utiliser de la POO dans une extension, je vous conseille WPPB.me qui permet de générer la base code POO nécessaire à la réalisation d’une extension WordPress (code dont je me suis pas mal inspiré).

Dans classes/AdvancedGutenbergBlocks.php vous trouverez l’appel à tous les blocs et toutes les classes PHP de l’extension.

J’ai également utilisé les espaces de noms PHP, ou namespaces, pour sécuriser mes noms de classes afin d’éviter les doublons avec le reste des extensions ou de WordPress.

On va maintenant aller voir du côté des blocs.

Du côté des blocs

Chaque Bloc est un objet PHP que j’ai instancié au démarrage de l’extension.  On va prendre l’exemple de classes/Blocks/Gmap.php.

Dans le cas où j’ai besoin de charger un script, un style particulier (en plus de ceux chargés dans classes/WP/Gutenberg.php), j’appelle à nouveau le hook enqueue_block_editor_assets.

Ici j’envoie simplement à JS la liste des styles de carte disponibles sous forme de variable globale JS, via la fonction wp_localize_script(). C’est la fonction officielle pour envoyer une donnée PHP vers JS.

Je charge aussi le script Google Map en fournissant la clé d’API enregistrée dans les options.

J’ai crée des fonctions register_block() et register_settings(). La première me permet de déclarer chacun de mes blocs (en PHP puisqu’ils sont déjà déclarés en JS).

Les paramètres de cette fonction me permettent d’indiquer des informations qui seront affichées dans la page options.

La deuxième fonction me permet de déclarer une option qui sera enregistrée par WordPress (c’est simplement une surcouche de register_setting(), fonction native de WP.

Enfin, la fonction register_render() me permet de rajouter le HTML de mes réglages du bloc, ici le champ clé d’API, qui sera affiché dans ma page settings.

En résumé j’ai fait un système à la WordPress : ma page Settings va récupérer tous les blocs que j’ai déclaré, et générer le rendu HTML. Via un hook, je vais pouvoir injecter des options.

Cela me permet de bien séparer mon code : les blocs sont déclarés dans leur fichier, la page d’option va ensuite générer le rendu à partir de tout ce qui aura été déclaré. Cette approche permet même à une extension tierce de venir profiter de la page d’options qui aura le rôle de tableau de bord de tous les blocs.

A l’avenir je pourrais donc facilement créer des add-ons pour mon extension, et ils viendront se brancher dans l’interface existante.

Alors, de votre côté vous n’avez pas besoin d’aller dans un tel niveau de complexité. Il vous suffit d’un fichier PHP, de déclarer le minimum (scripts et styles de Gutenberg) et ça marchera tout aussi bien.

Mon but ici était simplement de vous montrer une architecture possible pour une extension plus conséquente.


Dans les prochains cours on va s’attarder sur certains blocs en particulier, qui méritent qu’on y passe un peu de temps.

Si vous avez des questions sur la façon dont est faite mon extension, n’hésitez-pas à me les poser sur le Slack Capitaine WP ! Je me ferais un plaisir de vous répondre !

0

Questions, réponses et commentaires

Laisser un commentaire