Agence WordPress Be API | Actualités | WordPress | Débuter dans le développement de blocs Gutenberg en React : un retour d’expérience  

Débuter dans le développement de blocs Gutenberg en React : un retour d’expérience  

Publié le

par

Introduction

Cet été, chez Be API, nous avons démarré un projet interne nommé Blocks party dans le but de créer une collection de blocs Gutenberg complémentaire à la liste de blocs natifs de WordPress. Ces blocs seront faits-maison, et seront également bien évidemment open-source pour rester fidèle à l’ADN de WordPress.

Dans un premier temps, nous avons identifié les mises en forme / fonctionnalités les plus récurrentes dans nos projets, à partir desquelles nous avons produit une liste de blocs candidats pour le développement. Sans le savoir, j’allais commencer par le bloc le plus difficile et le plus complexe de la liste. 

Je suis Paolo Tesei, développeur de thèmes WordPress depuis 15 ans, et je vous propose ci-dessous un retour d’expérience sur la création de mon premier bloc Gutenberg natif.

Un parcours en forte pente

Tout est difficile quand on entame quelque chose de nouveau !

Pour commencer du bon pied, j’ai utilisé le paquet create-block de WordPress pour initialiser le projet, sous forme d’extension WordPress. J’ai ensuite ajouté nos coding standards habituels pour les langages JavaScript, CSS et PHP, puis je suis passé en mode multi-blocks (une extension permettant d’enregistrer plusieurs blocs à fois).

Personnellement, j’avais déjà commencé à prendre mes marques avec React en développant un site sous Gatsby.js. Avec Gutenberg l’expérience est similaire, comparable au développement à l’aide d’un Framework JavaScript : il faut s’adapter à ses règles et sa façon de fonctionner

Pour bien démarrer, la documentation (qui, à date, n’est pas encore optimale) reste la première pièce du puzzle, bien qu’il n’y est pas encore beaucoup d’exemples. Pour compenser ce manque, vu que tout est en open-source, il est plus facile de trouver et d’aller jeter un œil à l’utilisation que d’autres développeurs ont pu en faire (et de constater, ou non, s’ils sont également tombés dans les mêmes pièges que moi).

L’origine du mal

Le premier bloc que l’équipe projet a décidé de développer a été le bloc “Tabs”. Très demandé/utilisé dans nos projets, il s’agit d’un bloc composé d’une barre d’onglets (tabs list) et de panneaux de contenus (panels) avec un petit bonus permettant à l’utilisateur de choisir une icone pour chaque onglet. 

Comme nous avions déjà développé un bloc “Icons” qui permet de charger des collections d’icônes, j’ai préféré exploiter le système d’innerBlocks natif (blocs imbriqués) pour bien respecter le concept de modularité et d’indépendance des fonctionnalités, plutôt que de transformer ce bloc en composant.

Le Bloc “Tabs”

Capture d'écran de l'interface utilisateur du block tabs
UI du Be API Tabs Block

Après quelques jours passés à essayer de concevoir ce bloc à partir d’un seul bloc enfant, j’ai fini par réaliser qu’il n’en fallait pas moins de 4 pour faire le bloc de la manière la plus logique et cohérente !

Pour être plus précis, dans ce bloc “Tabs”, nous retrouvons les deux premiers blocs de niveau 1, un qui contient tous les onglets (tabs list) et un autre qui contient tous les panneaux (panels). Les enfants (niveau 2) de ces derniers sont synchronisés, ce qui veut dire que si je déplace le premier onglet (tab item) en deuxième position, le contenu (panel item) correspondant suivra et se positionnera dans le même ordre dans la liste des panels.

Dans cette phase, le plus difficile a été de comprendre comment faire parler les blocs entre eux. Dans Gutenberg, de base, chaque bloc vit sa vie, mais il existe plusieurs solutions pour permettre à ces blocs d’interagir. Bien sûr, il a fallu essayer chacune de ces méthodes pour déterminer celle qui serait la plus performante. J’ai donc utilisé les contextes (l’équivalent de Redux pour Gutenberg) et les Select et Dispatch pour récupérer la donnée dans le registre des blocks. Une autre piste était de créer un Store dédié, mais c’était clairement une solution surdimensionnée, donc vite abandonnée.

Petite contrainte (et astuce) : pendant toute la phase de développement, on casse souvent le block (autant de fois qu’on change la logique de développement) et une recontribution régulière est nécessaire pour le faire (re)fonctionner. Passage obligé, le message “Ce bloc a rencontré une erreur et ne peut pas être prévisualisé.” devient ton meilleur ami. Le message n’étant pas très explicite, il n’est pas évident de comprendre d’où vient l’erreur. Je conseille donc de développer petit à petit et de tester en continu pour éviter une frustration trop grande liée à des changements trop importants !

Si dans la majorité des cas, l’erreur vient d’un changement de markup, cette feature (non non, ce n’est pas un bug) met avant tout en évidence la fragilité des blocs. Il faut donc garder à l’esprit que si vous faites évoluer votre bloc dans le futur, il faudra prendre en compte sa rétrocompatibilité.

Nous avons commencé par établir (pour ce bloc, mais pour les suivants également) des règles générales de nommage pour préfixer nos blocs, nos classes et variables CSS et le namespace de nos plugins.

Pour rendre l’ensemble plus flexible et developer-friendly, nous avons rendu possible le fait de paramétrer quels types de bloc nous pouvons ajouter à l’intérieur des onglets (tabs) et de  la zone de contenu (panels), avec une liste de blocs autorisés (allowed blocks). 

Globalement, il faut réfléchir à comment rendre chaque bloc assez souple et ouvert pour qu’il puisse interagir avec les autres extensions/blocs de l’écosystème.

En parallèle, il faut également faire en sorte de brider l’interface efficacement, pour offrir aux contributeurs les moins expérimentés seulement les options qui leur seront utiles, ou bien tout simplement pour adapter l’édition du bloc à une direction artistique bien cadrée. 

Pour le bloc “Tabs”, j’ai désactivé l’édition de certains éléments (locking) pour éviter des erreurs de contribution et j’ai également rendu possible le fait de limiter et personnaliser la liste des alignements possibles.

En modifiant la configuration du blockSupport, il est également possible d’activer ou de désactiver l’affichage des options natives comme le sélecteur de couleurs ou la gestion des marges.

Une dernière source de réflexion concerne le CSS. En préparation de l’arrivée massive du FSE (Full Site Editing, plutôt Site editor (renaming récent)), il faut identifier quels sont les paramètres de styles qui permettent d’éditer l’aspect visuel du bloc, et ensuite créer les variables CSS associées.

Les trois règles

Dans le théâtre classique de 1500 inspiré par Aristote, la pièce parfaite devait être conçue en suivant les trois règles suivantes : 

  • l’unité de temps : tout se doit passer à l’intérieur d’une journée ;
  • l’unité de lieu : tout se doit dérouler dans les mêmes lieux/espaces ;
  • l’unité d’action : tous les événements principaux nécessaires à l’histoire doivent commencer et terminer à l’intérieur de la pièce. 

J’ai trouvé assez amusant de pouvoir appliquer ces « unités aristotéliques” dans le développement des blocs Gutenberg.

Unité de temps.

La vie d’un bloc s’étire d’une phase d’édition (edit) à une phase de sauvegarde (save), et ces deux phases sont intimement interconnectées. Il est fondamental de rendre l’interface d’édition fidèle au rendu front-office. C’est particulièrement vrai quand on développe un bloc qui n’a pas un rendu dynamique. Le markup de sa partie save impose aussi la structure de sa partie edit.

Unité de lieu

Ce concept est important pour la modularité : quand toutes les fonctionnalités ne peuvent pas être portées par un bloc seul, nous sommes contraints de décomposer ce dernier dans une structure parent > enfants. Cette règle est imposée par le fait que dans un bloc Gutenberg, nous avons le droit d’utiliser un seul innerBlock. Par exemple, le bloc natif “Buttons” (un wrapper innerBlock) est parent du bloc natif “Button”.

Unité d’action

Toutes les manipulations modifient les attributs du bloc simultanément. On doit donc essayer de privilégier un certain ordre d’interaction pour permettre une contribution la plus logique et naturelle possible :

  1. dans le contenu de la page (editor)
  2. dans la barre d’outils (toolbar) ou on accède à ces réglages principaux 
  3. dans la barre latérale (sidebar) ou on trouve ses options plus avancées. 

Conclusion

Même si au début, la mise en place a été un peu compliquée, j’ai pris énormément de plaisir à créer ce bloc.

En étudiant de plus près les blocs natifs (core blocks) de WordPress, j’ai pris conscience du soin et de l’importante réflexion derrière chaque bloc, ainsi que la quantité et la qualité de travail qu’il y a derrière le projet Gutenberg. 

Pour tout ce que j’ai appris/découvert, chapeau bas et merci à la communauté !