Formation « Créer des blocs avec Gutenberg »

Champs administrables et attributs

Lecture : 6 minutes • 2

On va maintenant voir comment offrir un peu d’interactivité à nos blocs en ajoutant notamment une zone de texte.

Jusque là nous avons des blocs statiques qui ne se révèleront pas super utiles. On va donc maintenant commencer à ajouter des zones de textes éditables pour rendre le tout un peu plus vivant.

On va maintenant prendre l’exemple dans src/3-edit. Pour rappel vous pouvez télécharger les sources de cette formation sur Github.

Dans ce cours l’objectif est d’ajouter un champ de texte simple qui va nous permettre de modifier le contenu de notre bloc. On va l’appeler content.

Voici le rendu attendu lorsque j’édite mon champ :

Et lorsqu’on le laisse tranquille :

Voici maintenant le code JS de ce bloc, et on commence tout d’abord par block.json :

JSON
src/3-edit/block.json

On va regarder ce code un peu plus dans les détails juste après mais on peut déjà remarquer qu’un nouveau paramètre a fait son apparition : attributes.

Rappel : ce qu’enregistre Gutenberg en base

Avant tout, il faut rappeler que Gutenberg enregistre en base le HTML du bloc (avec tous les autres blocs), c’est donc tout ce qui est dans save qui sera conservé à l’enregistrement de la page.  On peut d’ailleurs voir ce HTML dans le menu supérieur droit, puis Éditeur de code.

Le code source HTML généré par vos blocs
Le code source HTML généré par vos blocs

Je vous invite à revoir le cours dédié au cycle de vie de Gutenberg si jamais vous avez besoin de vous rafraichir la mémoire.

On a donc ici un problème : dans la base, la seule chose qu’il nous reste c’est un HTML statique. Il va donc nous falloir un moyen de dire à Gutenberg comment il doit récupérer les données modifiables, comme le contenu de notre champ content.

C’est ici que l’on fait appel aux attributs !

Les attributs et la méthode save

Toute donnée modifiable par l’utilisateur doit être déclarée dans les attributs. C’est comme ça que Gutenberg sait quelle donnée du HTML est administrable.

Pour l’instant on n’a qu’une seule donnée à enregistrer : content. C’est un texte que l’on retrouve dans le HTML de save, dans la balise qui a la classe .content.

JSON

On a donc 3 informations à indiquer :

  1. le type : une chaine de charactères « string » (mais ça pourrait être un nombre entier) ;
  2. la source : dans quel type d’élément je vais trouver ce contenu (ici dans la balise, mais ça peut être dans un attribut HTML par exemple) ;
  3. le sélecteur CSS qui va permettre de cibler l’élément à trouver.

En résumé, Gutenberg va chercher une chaine de caractères (1) dans le contenu d’une balise (2) dont la classe est nommée .content (3).

Voici ce que donne le code dans la partie save  :

JSX
src/3-edit/save.js

Gutenberg va donc désormais pouvoir lire le HTML et retrouver les données, où comme on les appelle ici les attributs de notre bloc.

D’autres types d’attributs

On va voir qu’il existe plusieurs types d’attributs disponibles dans Gutenberg. On devrait à peu près tous les voir au cours de la formation. Si vous voulez déjà vous familiariser avec les autres, je vous invite à jeter un oeil à la documentation Gwutenberg sur les attributs.

Un mot sur les classes CSS en JSX

Avez-vous remarqué que j’ai employé le mot-clé className et pas class dans mon HTML ? C’est normal, c’est une contrainte du langage JSX de React.

En fait quand le code est interprété ça reste du Javascript, et s’il voit le mot-clé class il va croire que c’est une classe JS (du point de vue programmation orientée objet).

C’est pour cela que React propose en remplacement className (avec un N majuscule).

Attention

Ne l’oubliez pas ! Quand on n’a pas l’habitude on a vite fait d’oublier. Et au début la moitié de mes erreurs provenait de là ! Alors notez le en rouge quelque part pour ne pas vous faire piéger !

En tous cas Emmet connait JSX et vous fera la bonne implémentation, si vous tapez p.content puis tabulation il autocomplètera alors correctement en <p className="content></p>.

Le changement de HTML dans save casse le bloc

Autre chose dont j’ai déjà fait mention dans le cycle de vie de Gutenberg mais qui est assez important pour en faire un petit rappel : quand vous changez le HTML d’un bloc, l’éditeur renverra une erreur lorsque vous rechargerez la page : le HTML reçu n’étant pas celui attendu.

Une erreur dans le contenu du bloc

C’est logique, mais du coup vous risquez de voir cette erreur souvent pendant le développement de vos blocs. Il suffit alors de supprimer et créer à nouveau le bloc.

Astuce : pour débuguer facilement, cliquez sur Comparer la conversion afin de voir le contenu attendu face au contenu réellement reçu.

Comparatif des versions attendues et reçues
On voit en rouge ce qui change entre les 2 HTML

La méthode edit

On vient de voir l’ajout des attributs et la légère modification du HTML contenu dans save mais le plus gros changement intervient du coup dans la méthode edit, car il faut intégrer notre champ de formulaire. Voici le code :

JSX
src/3-edit/edit.js

On note l’apparition d’une fonction onChangeContent() avant le return, c’est celle qui va permettre de transmettre le contenu modifié à Gutenberg.

On remarque aussi qu’il y a pas mal de nouveautés dans la fonction return, on va commencer par là.

Les props

Les props sont les données envoyées au bloc par un composant parent, ici l’éditeur. Elles sont nécessaires au bon fonctionnement de notre bloc, et peuvent contenir des variables, mais aussi des méthodes (ou fonctions).

Conseil

Avec React, si la donnée d’une props change, alors le bloc qui les utilise sera re-rendu. De cette manière, tout est toujours à jour dans une application React.

Du coup, si une donnée change, les composants concernés seront automatiquement mis à jour dans toute l’application. C’est un des principaux avantages face à jQuery.

On va maintenant continuer et observer plusieurs props utiles à notre composant.

props.isSelected

Dans notre bloc le but est que lorsque l’on ne touche pas au bloc, il a une apparence normale (la même qu’on aura en front), et quand on édite ce bloc, un champ texte apparait.

Pour cela on va utiliser la propriété props.isSelected qui est une valeur booléenne (vrai/faux) et qui indique si le bloc est actuellement actif ou non. En d’autre termes, si le rédacteur vient de cliquer dessus pour l’éditer ou non.

  • Si oui : j’affiche le champ texte,
  • si non : j’affiche simplement la valeur dans un paragraphe.

props.attributes

Notre valeur content a été définie comme un attribut de notre bloc, Gutenberg va donc nous la mettre à disposition via props.attributes.content. Et on le met entre accolades { ... } pour l’afficher dans du HTML, comme on le ferait dans n’importe quel langage de templating.

Information

En fait la valeur des attributs n’est pas stocké dans notre composant bloc, mais en amont dans Gutenberg, qui centralise toutes les données. C’est pour cela que l’on utilise props à chaque fois : la donné est transmise par le parent via les props.

Le champ input

C’est un simple champ input basique qui est utilisé ici. On verra cependant dans les prochain cours que WordPress propose des composants déjà tout faits pour des champs de formulaires ou boutons, qui nous seront fort utiles.

Dans les attributs on commence déjà par attribuer la valeur { props.attributes.content } dans l’attribut value du champ de texte (sinon la valeur ne sera pas réaffichée la prochaine fois que vous lancerez l’éditeur).

On assigne ensuite à l’événement onChange la fonction onChangeContent() qui sera lancée lorsque le contenu du champ sera modifié.

D’ailleurs notez qu’on revient ici aux bases du JS : on applique la fonction directement dans la balise, contrairement à jQuery qui externalisait tout et opérait à renfort de sélecteurs $('input').change().

La fonction onChangeContent()

Cette fonction va nous permettre de réattribuer la nouvelle valeur de notre contenu lorsqu’on la change. On utilise la fonction props.setAttributes fournie par Gutenberg en amont pour mettre à jour l’attribut « officiellement ».

Notre fonction récupère l’événement qui l’a lancée, et on obtient la valeur par event.target.value, qui ça aussi, est du JS absolument classique !

D’ailleurs on a bien la notation de fonction en fat arrow comme on a pu le voir sur les bases ESNext. J’aurais très bien pu écrire la version « classique », mais je vous conseille vivement d’opter pour la nouvelle syntaxe.

JSX

À éviter

En réalité je vous ai mené sur une fausse piste : WordPress propose un champ Input adapté aux blocs qui s’appelle Textcontrol. On le verra en temps voulu, lors de l’exemple du champ URL.


Et voilà ! vous avez votre premier bloc administrable. Un petit pas pour le développeur, un grand pas pour l’édition de contenu en temps réel !

Dans le prochain cours on va voir un composant bien plus sympa que notre champ de texte de base : le champ RichText qui nous permettra pleins de super choses.

2

Questions, réponses et commentaires

  1. pirla

    Le 7 mars 2023

    typo :
    “Voici maintenant le code JS de ce bloc, et on commence tout d’abord par index.js :”

    Non, ce qui suit est block.json

    1. Maxime BJ

      Le 7 mars 2023

      En effet, le cours date d’avant le changement de structure du plugin. J’avais mis à jour le code, mais j’ai oublié de mettre à jour cette phrase. Merci, c’est corrigé.

Laisser un commentaire