Formation « Créer des blocs avec Gutenberg »

Le champ RichText et la Toolbar

Lecture : 6 minutes • 4

Gutenberg nous propose différents champs pour améliorer l’expérience de l’éditeur, dont notamment le RichText qui se présente un peu comme le successeur de TinyMCE. Il va nous permettre de mettre en forme nos contenus grâce à une barre d’outils complètement personnalisable.

Dans le cours précédent l’exemple était peu concluant : on avait un champ input de type text qui héritait des styles par défaut de WordPress.

C’est un champ que l’on va pouvoir utiliser dans le panneau des options de droite (l’inspecteur), mais pas tellement dans nos blocs.

On va donc utiliser le composant RichText, mis à disposition par Gutenberg, pour créer nos zones éditables. Ce champ est très grandement personnalisable et vraiment pratique à utiliser.

Capture d'écran du composant RichText et de sa Toolbar en action
Le composant RichText, avec sa barre d’outils

Ouvrez l’exemple src/4-richtext que l’on va étudier plus en détails. Le code de ce bloc va rester en grande partie identique à l’exemple du cours précédent.

Rappel : vous pouvez télécharger tous les exemples de la formation sur Github.

On va ouvrir le fichier edit.js afin de voir comment utiliser le composant RichText :

JSX
src/4-richtext/edit.js

Utiliser le composant RichText et sa Toolbar

En tout premier lieu, il faut indiquer que l’on veut utiliser le composant RichText, et pour cela il faut l’importer depuis la librairie @wordpress/block-editor. Ça tombe bien, on chargeait déjà useBlockProps de cette librairie, donc on va simplement ajouter RichText à la liste.

On n’a pas encore vu à quoi sert cette fonction d’ailleurs, mais pas d’inquiétude : on va le voir très bientôt.

Ensuite, à la place du <input>, on utilise le composant RichText comme si on appelait une simple balise HTML. C’est ça la puissance de React.

À l’intérieur, on a des attributs qui permettent de passer des paramètres de configuration.

Les attributs du RichText

Isolons le code du RichText, afin de regarder plus en détail chacun des attributs :

JSX

Le premier paramètre, tagName, indique que l’on veut que ce composant soit rendu sous forme d’un paragraphe. On aurait tout autant pu choisir une div pour l’occasion.

Ici le but est de faire ressembler l’éditeur le plus possible à la balise qu’il représente lors du rendu.

Le placeholder, la value et l’événement onChange sont exactement les mêmes que pour un simple champ text.

L’attribut className permet de donner un style au champ mais également de lier à l’attribut content (à qui on a mis un sélecteur .content).

On va voir un peu plus tard d’autres paramètres disponibles pour ce composant.

La disparition du props.isSelected

On a ici le droit à une petite simplification : le props.isSelected disparait. Retenez-le tout de même car on va continuer à l’utiliser plus tard dans d’autres situations.

Mais ici il n’est plus nécessaire : en effet le bloc RichText n’a pas d’apparence visuelle spécifique donc quand on ne le touche pas, il ressemble en définitive à ce que l’on veut. Pas besoin donc de le remplacer par un simple paragraphe lorsque le focus disparait.

Changements dans la fonction d’enregistrement

On va avoir également un petit changement dans la fonction de mise à jour de l’attribut onChangeContent() : on n’a plus besoin de récupérer l’événement afin d’accéder à event.target.value car les composants Gutenberg renvoient directement la bonne valeur :

JSX

Grâce à ESNext on peut simplifier { content: content } afin d’écrire simplement { content }.

Mais on peut encore aller un peu plus loin : écrire l’attribution directement dans l’attribut onChange du RichText :

JSX

Et dans ce cas on n’a même plus besoin de notre fonction onChangeContent ! J’ai appliqué ce changement dans l’exemple 5, que l’on aborde juste après.

C’est un peu moins clair quand on n’a pas l’habitude, donc choisissez l’écriture qui vous convient le mieux. À mes débuts j’ai voulu aller trop vite en besogne lors de mes débuts React et je ne comprenais plus ce que j’écrivais !

Par contre, vous ne pourriez pas utiliser cette écriture si vous aviez besoin de traiter votre donnée avant de l’enregistrer dans les attributs (faire quelque chose avec la donnée avant de l’enregistrer).

Ici ça fonctionne car on n’a qu’une seule instruction (= qu’une seule ligne de code).

Changements dans les attributs

Dans le cours précédent on avait utilisé l’attribut de cette manière dans index.js :

JSON

On indiquait que la valeur content était une chaine présente dans le contenu de la balise nommée .content.

L’éditeur RichText se comporte un peu comme l’ancien TinyMCE : Il est possible de faire de la mise en forme comme du gras, italique, souligné, des retours à la ligne et même des sauts de lignes.

Et tout cela génère bien entendu des balises HTML. Donc on doit adapter notre attribut de cette manière :

JSON

Le type reste une chaine « string », qui peut désormais contenir du HTML (donc du texte et des balises). La source est donc « html » : Gutenberg comprend alors qu’il doit récupérer tout le contenu intérieur de la balise, sous-niveaux compris, et que tout ceci est le contenu administrable dans notre éditeur riche.

Conseil

De manière générale, vous appliquerez toujours cette configuration lorsque vous utiliserez le composant RichText.

Changements dans le save

Et enfin, on a quelques changements à apporter dans notre méthode save. Pour cela regardons le fichier save.js :

JSX
src/4-richtext/save.js

Afin que Gutenberg interprète correctement le HTML issu de notre RichText, il faut utiliser le composant RichText.Content dans le save().

On indique là aussi la classe content, et qu’on veut que la balise soit un paragraphe.

Le Richtext multiligne

Si vous essayez en l’état d’appuyer sur Entrée, vous n’aurez qu’un retour à la ligne <br> et non pas un nouveau paragraphe. Pour corriger ça on va passer en mode multiligne.

Actuellement notre RichText est déjà un paragraphe, et en HTML il est interdit d’imbriquer des paragraphes ensemble (car sémantiquement, ça n’a aucun sens).

On va devoir donc dire que notre RichText est une div qui peut contenir des paragraphes, et pour cela il faut changer l’attribut tagName et ajouter un attribut multiline.

Vous trouverez le code complet dans l’exemple 5 : src/5-richtext-multiline.

JSX

Dans cette configuration on indique que notre éditeur est une div qui va contenir des paragraphes. A chaque pression sur la touche entrée, un nouveau paragraphe sera créé !  Simple et efficace !

Mais ça ne s’arrête pas là ! Vous pourriez très bien dire que le conteneur est une liste <ul>ou <ol>, et chaque retour à la ligne créera un nouvel élément de liste <li> :

JSX

Il faut par contre penser à adapter le rendu en conséquent, mon <p className="content"> présent dans edit et save devra alors être modifié en une divul ou li.


Il existe d’autres attributs encore plus poussés pour le RichText, si vous voulez les découvrir je vous invite à consulter la documentation de ce composant sur Github. Pour rappel chaque composant ou bloc Gutenberg est accompagné de son readme et affiché sur Github.

Documentation du composant RichText

La documentation développeur vous apportera aussi des explications sur l’utilisation du RichText.

Personnaliser les options de la Toolbar

Pour l’instant, on a utilisé la Toolbar par défaut mais sachez qu’on va ensuite pouvoir la personnaliser, et même ajouter nos propres fonctions sur mesure, ce que l’on verra dans un prochain cours.

Si vous aviez personnalisé TinyMCE par le passé, vous savez que c’était compliqué et peu pratique. Mais là vous allez voir que c’est un vrai régal !

Pour le moment, on va simplement définir les options natives que l’on veut afficher ou non.

On va aller voir maintenant du côté de l’exemple 6 : src/6-richtext-toolbar et plus précisément dans edit.js :

JSX
src/6-richtext-toolbar/index.js

L’attribut allowedFormats nous permet de définir les boutons à afficher ou non dans cette barre d’outils.

Gérer l’alignement du bloc

Le bloc paragraphe propose de choisir l’alignement : à gauche, centré ou à droite mais notre bloc non. Si on veut faire pareil, on peut utiliser l’attribut supports dans la définition du bloc :

JSON
src/6-richtext-toolbar/block.json

Le problème, c’est que c’est le bloc qui va être aligné, via un float CSS, et du coup ça va faire n’importe quoi.

En réalité, ce que l’on veut, c’est appliquer le résultat directement sur le RichText, afin d’aligner ses textes, et non pas le conteneur.

du coup, on va ajouter nous-même la barre d’outils, et contrôler l’alignement correctement dans le prochain cours.

À éviter

On va donc éviter cette technique, je vous invite à commenter ou retirer l’attributs supports de ce bloc.


Et bien voilà ! On vient au bout d’un cours tout de même assez intense avec pleins de nouvelles notions importantes. On apprendra plus tard à personnaliser cette toolbar avec nos propres fonctions.

Pour l’instant on peut dire que notre bloc commence à être un peu mieux, mais il est quand même moche : c’est pour cela qu’après avoir réglé le souci d’alignement, on va enchainer avec un cours sur la gestion du CSS de nos blocs avec Sass.

4

Questions, réponses et commentaires

  1. pirla

    Le 7 mars 2023

    Typo :
    L’exemple dans block.json:
    “align”: [‘left’, ‘right’, ‘center’], plante le compilateur.
    Il faut
    “align”: [“left”,”right”,”center”]

    1. Maxime BJ

      Le 7 mars 2023

      En effet, comme c’est du JSON, seuls les double quotes sont autorisées ! J’ai corrigé, Merci beaucoup !

  2. pirla

    Le 7 mars 2023

    Typo :
    L’attribut formattingControls nous permet de définir les boutons à afficher ou non dans cette barre d’outils.
    Non, dans l’exemple c’est allowedFormats .

    1. Maxime BJ

      Le 7 mars 2023

      Merci ! Je corrige. C’est en effet le nom de l’ancien paramètre (< 2020).

Laisser un commentaire