Un bloc sur mesure c’est quand même mieux lorsqu’on peut modifier son contenu. Et justement, dans ce cours on va voir comment déclarer nos données éditables via les attributs et le composant RichText pour bénéficier d’un éditeur de texte riche.
Sommaire du cours
Jusqu’à maintenant, notre premier bloc était personnalisable grâce aux supports, mais on ne pouvait pas modifier le contenu de celui-ci.
On va remédier à cela dans ce cours. Et pour cela on va aborder 2 concepts très importants :
- Les attributs de blocs, qui vont nous permettre de déclarer des valeurs dynamiques ;
- Le composant
RichText, qui va nous fournir une interface sympa pour éditer nos contenus en direct.
Les attributs de bloc
On va commencer avec les attributs. Un attribut permet d’indiquer à Gutenberg une valeur administrable, non statique, qui peut bouger dans le temps et qui devra donc être enregistrée avec le bloc.
Vidéo premium
Cette vidéo est réservée aux détenteurs de l’offre premium.
Envie de nous rejoindre ?
Voici l’exemple que l’on va étudier dans ce cours :
Le bloc s’appelle « RichText » et son code se trouve dans le dossier /src/03-richtext/ de mon plugin de blocs.
Dans cet exemple, le texte en violet est administrable. D’un simple clic sur celui-ci, on peut l’éditer. La barre d’outils au dessus permet même de mettre en gras, italique, ou encore d’ajouter un lien.
C’est notre composant RichText, que l’on verra plus en détails dans la suite de ce cours. Pour l’instant, écrivez simplement un texte dans ce bloc.
Quel est le but des attributs ?
Afin de bien comprendre le rôle et l’utilité des attributs, on va d’abord aller regarder du côté du HTML généré par WordPress lorsque l’on modifie le contenu du bloc.
Vidéo premium
Cette vidéo est réservée aux détenteurs de l’offre premium.
Envie de nous rejoindre ?
Pour cela, cliquez sur les 3 points en haut à droite de l’écran et sélectionnez « Éditeur de code ».
Comme vous pouvez le voir, Gutenberg génère un code HTML où chaque bloc est séparé des autres par des commentaires.
C’est justement ce code HTML qui sera enregistré dans la base de données, au sein de la table wp_post.
Mais du coup, comment WordPress va savoir comment récupérer le contenu administrable au prochain chargement de l’éditeur ?
Pour cela, il va devoir parser (= interpréter) le HTML à partir d’instructions qu’on va lui indiquer. Ainsi, il sera en mesure de récupérer chacune des données et options personnalisables.
C’est là qu’entrent en jeu nos fameux attributs !
Définir les attributs
Pour indiquer à Gutenberg qu’il y a un contenu modifiable à l’intérieur du bloc, on va déclarer des attributs.
Vidéo premium
Cette vidéo est réservée aux détenteurs de l’offre premium.
Envie de nous rejoindre ?
Pour cela, on va utiliser la propriété attributes de notre block.json et ça peut ressembler à ceci :
Dans cet exemple on peut voir que j’ai déclaré un seul attribut appelé content, mais on peut en déclarer autant que l’on veut. On verra d’ailleurs quelques exemples avec 5-10 attributs plus tard dans la formation.
Mais pour le moment, on va décortiquer quelques exemples isolés pour comprendre le principe des attributs.
Déclarer un contenu HTML administrable
Dans le bloc de mon plugin, j’ai déclaré une donnée que j’ai nommée content et qui me permettra de sauvegarder mon contenu administrable.
À l’intérieur de content, je dois indiquer plusieurs informations :
type: le type de donnée qui sera enregistrée dans l’attribut, ici une chaîne de texte ;source: indique où on va trouver le contenu , ici dans le HTML ;selector: le sélecteur CSS indique à quel endroit trouver le contenu dans le HTML ;default: l’éventuelle valeur par défaut à afficher à l’insertion du bloc ;role: indique que le contenu reste administrable même si le bloc est verrouillé.
Ici, le sélecteur est très simple : un simple p. Notre bloc est très simple et possède un seul paragraphe, donc ça ne posera pas de souci. Mais dans de futurs exemples, on utilisera un sélecteur beaucoup plus précis à l’aide de classes CSS.
Donc maintenant, Gutenberg sait que le contenu HTML à l’intérieur du paragraphe est administrable.
Ce qui veut dire qu’il sera capable de récupérer l’information au prochain chargement du contenu dans l’éditeur : à partir du HTML enregistré, il saura retrouver la valeur du texte administrable.
Déclarer un attribut HTML administrable
Pour mettre les choses en perspective, voici un autre exemple, avec cette fois un attribut qui permettrait de définir une URL dans un lien :
Cette fois, on observe quelques différences avec l’exemple précédent :
type: c’est toujours une chaîne de texte ;source: cette fois on indique qu’on va trouver le contenu dans un attribut HTML, et pas directement dans du HTML ;attribute: on définit quel attribut de notre balise HTML doit être visé, icihref;selector: le sélecteur est cette fois le lien.
Dans cet exemple, on indique à Gutenberg que la donnée est un texte, stockée dans l’attribut href d’une balise <a>.
Pour cela, on a ajouté une quatrième propriété attribute pour définir quel attribut HTML est visé, car au final une ancre peut en avoir plusieurs : class, id, href, target…
Avec ce HTML en sortie, la définition de notre attribut est la bonne :
Gutenberg va bien trouver une balise <a> dans notre bloc et retrouvera la valeur dans son attribut href.
Déclarer une valeur booléenne administrable
Enfin, on va également pouvoir enregistrer une valeur qui n’aura pas sa place dans le HTML du bloc, par exemple une valeur booléenne qui nous permettra de définir si le bloc a une bordure ou non.
Dans ce cas, on indique uniquement le type, qui est ici un booléen, et sa valeur par défaut : vrai ou faux.
Du côté du HTML généré par Gutenberg, la valeur sera enregistrée en JSON dans le commentaire de délimitation du bloc :
En résumé : du HTML aux attributs
Lorsqu’on vient éditer notre page dans l’interface d’administration, voici ce qu’il se passe :
- Gutenberg récupère le contenu HTML brut enregistré en base ;
- Il interprète ce HTML (= parsing) pour séparer chaque bloc avec les commentaires ;
- Il recherche les attributs grâce aux instructions du
block.json; - Enfin, il transforme tout ça en blocs interactifs et administrables.
C’est grâce à nos attributs définis plus tôt qu’il sait où chercher. Si on écrit ceci dans block.json :
Alors l’éditeur va chercher dans le HTML le paragraphe <p> afin d’extraire son contenu et le stocker dans la variable content, que l’on va exploiter juste après.
Ne vous inquiétez pas, on va revoir ce concept un peu plus tard dans la formation lorsqu’on abordera le cycle de vie de Gutenberg, afin de bien comprendre ce qu’il se passe sous le capot.
Utiliser les attributs dans notre composant
Maintenant que vous avez compris le fonctionnement des attributs, on va voir comment les utiliser dans notre code.
Vidéo premium
Cette vidéo est réservée aux détenteurs de l’offre premium.
Envie de nous rejoindre ?
Voici le fichier edit.js :
Et également le fichier save.js :
Les attributs ne sont pas gérés au niveau du bloc, mais globalement au niveau de l’éditeur Gutenberg lui-même. C’est donc ce dernier qui va vous les envoyer via les paramètres des fonctions Edit() et save().
En React les fonctions qui vont afficher du HTML à l’écran sont appelés des composants. Elles finissent donc par un return() qui contient du pseudo HTML, ce qui n’est d’ailleurs pas possible en JS natif. C’est pour cela qu’on a besoin de compiler les fichiers JS React qu’on appelle également JSX.
Le saviez-vous ?
Les fichiers React peuvent porter l’extension .jsx mais ça fonctionnera tout autant si vous laissez .js, le compilateur saura les compiler quand même.
Les paramètres passés aux fonctions composants sont appelés les props.
Dans le cas de WordPress, on reçoit plusieurs props dont les attributes et la fonction setAttributes qui va nous permettre de les mettre à jour.
Et dans attributes, on va retrouver notre variable content ! On a donc un objet props qui contient un objet attributes qui contient à son tour la variable content. On pourrait donc afficher cette valeur comme ceci :
Mais à la longue ça sera un peu répétitif. Heureusement pour nous, JavaScript nous propose une syntaxe un peu plus intelligente ! On va extraire les variables des objets pour les utiliser directement :
C’est un peu l’équivalent JS de la fonction extract en PHP au final.
La syntaxe vous parait un peu bizarre ? Pas d’inquiétude, on va se familiariser avec les syntaxes du JS moderne et de React très bientôt dans cette formation.
Le composant RichText
On sait comment récupérer et lire un attribut grâce aux props passées à nos composants. Maintenant, on va voir comment rendre cette valeur administrable.
Vidéo premium
Cette vidéo est réservée aux détenteurs de l’offre premium.
Envie de nous rejoindre ?
Et c’est justement le composant <RichText /> de Gutenberg qui va nous permettre de rendre cela possible.
Ce composant, vous le connaissez déjà, car il est notamment utilisé par le bloc le paragraphe pour nous permettre d’écrire du contenu et le mettre en forme :
Et ce composant, on va pouvoir l’utiliser facilement de notre côté, comme tous les composants créés pour WordPress d’ailleurs.
On verra dans le cours sur les réglages de l’inspecteur comment on va pouvoir réutiliser champs, boutons on/off, sélecteurs de couleurs… pour ajouter des options à nos blocs sans avoir à réinventer la roue, ce qui nous permettra d’avoir une interface unifiée et harmonieuse.
Le composant RichText dans Edit
Voyons maintenant comment l’utiliser dans notre code. Voici edit.js pour commencer :
Pour utiliser un composant, il faudra d’abord l’importer au début du fichier. RichText appartient à la librairie block-editor de WordPress, au même titre que useBlockProps().
On l’importe donc sur la même ligne :
Ok, on va désormais pouvoir l’utiliser !
Maintenant, dans le return() d’une fonction React (un composant donc), on va pouvoir afficher du HTML, mais également invoquer d’autres composants.
C’est ce que l’on fait avec RichText : on l’appelle comme si c’était une balise HTML classique au final.
On doit déclarer plusieurs attributs :
tagName: le type de balise qui va englober notre contenu, ici j’ai choisi un paragraphe ;placeholder: un texte d’aide qui s’affiche lorsque le champ est vide et sans valeur par défaut ;value: la valeur du champ, c’est donc ici que l’on reporte notre attributcontent;onChange: la fonction à lancer lorsqu’on modifie la valeur de notre contenu. C’est ici que va intervenirsetAttributes.
Pour ce dernier, j’ai employé une formulation très synthétique, et il se peut que vous ayez du mal à la comprendre. Je vais donc écrire tout ça autrement :
Cette fois, sur l’événement onChange de mon composant RichText, j’invoque une fonction onChangeContent() que j’ai déclaré un peu plus haut dans le composant.
Cette fonction va recevoir en paramètre le nouveau contenu, nommé newContent. À l’intérieur, je vais simplement assigner ce nouveau contenu à mon attribut content, en passant par la fonction setAttributes().
Le saviez-vous ?
En React, vous ne pouvez pas mettre à jour un attribut directement, il faudra impérativement utiliser la fonction dédiée. Vous savez pourquoi ?
Si vous mettez directement à jour une valeur, React n’aura aucun moyen de savoir que la valeur a changé, et ne pourra donc pas rafraîchir automatiquement tous les composants qui utilisent cette valeur.
C’est pour ça qu’on passe par une fonction dédiée. Ainsi, React est mis au courant et pourra effectuer tous les changements nécessaires et re-rendre les composants impactés.
Si cette approche vous semble plus lisible, vous pouvez alors la privilégier dans votre code. À mes débuts, c’est celle que j’utilisais car je me sentais plus à l’aise avec.
Mais revenons à la version optimisée :
Ici en fait, au lieu d’appeler une fonction qui sera utilisée que dans ce cas, on invoque directement ce que l’on appelle une fonction anonyme. C’est une fonction sans nom à usage unique.
Vous les avez déjà utilisées si vous avez déjà fait du jQuery mais avec une syntaxe un peu différente :
Revenons-en à notre exemple : dans notre cas, dans la première partie, on récupère les paramètres de la fonction, ici content, c’est le contenu que le RichText vous renvoie.
Ensuite, le mot function n’apparaît pas car on a utilisé la syntaxe de la fat arrow, où la fonction est représentée par une grosse flèche =>, que l’on va bientôt revoir en détails.
Ce qui suit est le contenu de la fonction. En JS, si la fonction comprend une seule instruction, on peut retirer les accolades, c’est pour ça qu’on a directement setAttributes() après.
Et enfin, lorsqu’on est sur le point de répéter une clé avec la valeur à assigner, on peut regrouper :
En d’autres termes, le contenu récupéré par le RichText est assigné au contenu dans notre attribut.
Si vous n’êtes pas encore à l’aise avec les syntaxes JS modernes, pas d’inquiétude, comme je vous le disais, j’ai prévu un cours à ce sujet un peu plus tard dans la formation.
Le composant RichText dans save
Pour terminer, on va voir comment récupérer notre attribut pour l’enregistrer en base via le composant save.
Pour rappel, le fichier save.js permet de définir à quoi va ressembler le HTML généré à sauvegarder en base de données.
Notez que là aussi, on utilise le composant RichText, ou plus précisément, le sous-composant RichText.Content.
On doit cette fois simplement indiquer le nom de la balise via tagName et la valeur de notre attribut via value.
À ce point vous demandez peut-être pourquoi ne pas faire directement ça ?
C’est d’ailleurs ce que l’on faisait au tout début de l’ère Gutenberg ! Mais passer par le composant permet à WordPress d’opérer certains traitements sur la donnée en vue de son enregistrement.
Cela permettra aussi de rester toujours compatible si le RichText venait à évoluer dans le futur.
Donc passez toujours par RichText.Content si vous avez utilisé RichText dans edit.js !
Limiter les options de formatage du RichText
Enfin, avant de terminer ce cours, voici une petite astuce concernant les options du RichText !
Vidéo premium
Cette vidéo est réservée aux détenteurs de l’offre premium.
Envie de nous rejoindre ?
Dans le RichText, il y a beaucoup d’options de formatage proposées de base notamment via la petite flèche à droite.
Par exemple, j’utilise souvent « Code en ligne » pour afficher des variables dans mon texte.
Heureusement, vous allez pouvoir limiter les choix grâce à l’attribut allowedFormats :
Dans cet exemple, j’ai uniquement autorisé le gras et l’italique. Il ne sera donc pas possible d’ajouter un lien !
Pour connaître la liste complète des formats, ne comptez pas trop sur la documentation. Mais voici une autre astuce. Inscrivez cette commande dans la console du navigateur :
Vous devriez obtenir une liste qui ressemble à ceci :
core/bold: mettre le texte en gras ;core/code: code en ligne ;core/image: insérer une image en ligne ;core/italic: mettre le texte en italique ;core/link: ajouter un lien dans le texte ;core/strikethrough: barrer le texte ;core/underline: souligner le texte (déconseillé, générélement réservé aux liens) ;core/text-color: Changer la couleur d’une partie du texte ;core/subscript: Indice ;core/superscript: Exposant ;core/keyboard: Mettre en avant un raccourci clavier ;core/unknow: Supprimer une mise en forme non reconnue ;core/language: Définir la langue d’un mot ou d’une expression ;core/non-breaking-space: Ajouter un espace insécable ;core/footnote: Insérer une note de bas de page.
À vous de choisir ceux que vous souhaitez conserver ou retirer de la sélection, afin de proposer une ergonomie épurée à vos clients.
Bon, c’était un cours plutôt intense mais essentiel à la bonne compréhension du fonctionnement des blocs Gutenberg.
Entre les attributs, le composant RichText et les syntaxes JS un peu biscornues, il y avait pas mal à assimiler.
Mais ne vous inquiétez pas, on va voir et revoir ces concepts dans les prochains cours, et tout devrait devenir plus clair avec la répétition.
Dans le prochain chapitre, on va voir comment ajouter des réglages à nos blocs, faire des blocs enfants et gérer la retro-compatibilité de nos blocs…
Dans le prochain cours, on va commencer par ajouter des réglages à la barre d’outils au dessus de nos blocs !
0
Questions, réponses et commentaires