Tout comme avec PHP, il est possible d’utiliser des hooks WordPress en JS afin de modifier le comportement de blocs existants. Ça peut être très pratique pour améliorer un bloc natif par exemple, sans avoir à le refaire.
Sommaire du cours
- Objectif : ajouter des paramètres à un bloc existant
- Déclarer les hooks
- Hook #1 : Ajout d’un nouvel attribut dans le bloc
- Hook #2 : Ajout des champs dans l’inspecteur du bloc
- Hook #3 : Ajout de la classe dans le bloc dans l’éditeur
- Hook #4 : Ajout de la classe dans le HTML sauvegardé
- Découvrir d’autres filtres
Dans ce cours, on va voir comment tirer parti des hooks JS de Gutenberg, afin de modifier le comportement de blocs existants.
Hooks
Définition
Le fonctionnement est un peu le même que pour les Hooks en PHP, qu’on a pu aborder dans la formation développeur de thème, mais la syntaxe à l’intérieur sera un peu différente, à cause de la nature même de React.
Mais vous allez voir, ce n’est pas très compliqué une fois qu’on a compris le principe !
Objectif : ajouter des paramètres à un bloc existant
Dans ce cours, je vais vous montrer comment modifier le comportement d’un bloc existant sans modifier directement son code source. Le but étant de lui ajouter de nouveaux paramètres qui n’étaient pas présents nativement.
Pour cela, j’ai déclaré un bloc 17-hooks dans le plugin d’exemple qui va nous permettre de nous exercer.
C’est ce bloc que l’on va hooker. Bon, c’est un peu bête car on a accès au code et on pourrait le modifier à volonté : mais on va tout de même utiliser les hooks pour comprendre le principe.
De là, vous pourrez hooker n’importer quel bloc existant, qu’il soit issu du coeur de WordPress ou d’une autre extension.
Notre bloc est tout simple : il ne propose aucune option particulière, un peu comme les tous premiers blocs de la formation.
Ce que l’on aimerait maintenant, c’est ajouter une option dans l’inspecteur pour changer la taille du texte dans le bloc : petit, moyen, ou grand.
Pour en arriver là, on va devoir faire 4 actions. Il faut :
- D’abord ajouter un nouvel attribut
size
pour sauvegarder notre option ; - Ensuite insérer notre champ select dans l’inspecteur ;
- Ajouter la classe CSS (petit, moyen, grand) à notre bloc dans l’éditeur ;
- Ajouter la classe CSS au HTML enregistré du bloc pour le front.
Ces 4 actions vont s’effectuer via 4 hooks (filtres) différents, fournis par WordPress.
On va maintenant se rendre dans le fichier hooks.js
pour voir comment fonctionnent nos hooks.
Déclarer les hooks
Pour déclarer les hooks, on va faire appel à la fonction addFilter()
fournie par WordPress.
Il faut bien penser en premier lieu à importer la librairie addFilter
de WordPress, en haut du fichier.
Ensuite, la fonction addFilter()
possède 3 arguments. Le premier est le nom du hook sur lequel on veut se brancher.
blocks.registerBlockType
se branche sur la définition du bloc, et nous permet d’accéder aux attributs de celui-ci.editor.BlockEdit
se branche au code du bloc pendant l’édition, et nous permet d’ajouter nos propres champs de paramètres dans l’inspecteur.editor.BlockListBlock
se branche au moment du rendu du bloc dans l’éditeur, et nous permet d’ajouter la classe CSS custom dans l’éditeur.blocks.getSaveContent.extraProps
se branche au moment de l’enregistrement du bloc en HTML et nous permet d’ajouter notre classe CSS pour le front.
Le second paramètre de la fonction permet de nommer notre hook. On va lui donner un nom arbitraire, mais unique, afin de ne pas faire conflit avec d’autres éventuels hooks présents sur ces actions.
Enfin, le troisième argument est la fonction de callback, c’est à dire la fonction que WordPress doit appeler lorsqu’il atteint l’action concernée.
On va maintenant étudier chacune de ces fonctions en détails.
Hook #1 : Ajout d’un nouvel attribut dans le bloc
Comme en PHP, ces hooks sont appelés dès que WordPress déclenche l’action. Cela veut dire que notre fonction va se lancer pour chaque bloc de l’éditeur. Mais ce n’est pas ce que l’on veut. On veut exécuter ce hook uniquement pour un bloc bien précis.
La première chose à faire va donc être de vérifier qu’on est bien dans le bon bloc.
Au début du fichier, on va déclarer une constante allowedBlocks
dans laquelle on va définir le ou les blocs concernés par nos hooks. Ici, j’ai simplement ciblé mon bloc, mais on aurait pu très bien ajouter d’autres blocs, comme par exemple :
Si vous avez suivi la formation « Développeur de thèmes », vous vous souvenez probablement que lorsqu’on utilisait le hook save_post, on vérifiait avant toute chose que l’on était bien dans le bon type de publication avant de continuer.
Eh bien là, c’est la même chose : au début de notre fonction, on va vérifier qu’on est bien dans le bon bloc grâce à la méthode includes()
. Le nom du bloc est automatiquement fourni en second paramètre du hook WordPress : name
.
Ensuite c’est tout simple : si on est dans le bon bloc, alors on va insérer dans settings.attributes
(l’objet qui contient tous les attributs du bloc) notre nouvelle donnée à enregistrer : size
.
Pour rappel, les attributs sont les données personnalisables d’un bloc, que l’on déclare généralement dans block.json
.
On vient donc ajouter notre attribut size
aux attributs déclarés initialement par le bloc, sans modifier le code source original du bloc. C’est là toute la puissance des hooks !
Hook #2 : Ajout des champs dans l’inspecteur du bloc
Maintenant qu’on a notre nouvel attribut, il va falloir injecter notre champ select dans l’inspecteur du bloc, afin de pouvoir donner à l’utilisateur la possibilité de changer la valeur. Voici le code du hook. Celui-ci est un peu plus conséquent :
Tout d’abord, on peut voir l’usage de la fonction createHigherOrderComponent()
, qui permet de surcharger un composant React existant.
En d’autres termes : on prend un composant (notre bloc) et on lui ajoute d’autres éléments (notre champ select).
C’est en réalité une technique propre à React, qui s’appelle High Order Component (ou HOC).
Le bloc qu’on s’apprête à surcharger sera appelé Block
dans la fonction, il est passé en premier paramètre du HOC.
La première chose que l’on va faire, là encore, c’est tout d’abord vérifier qu’on est bien dans le bon bloc, via :
Cette fois, le nom du bloc est récupéré dans les props (via props.name). Si on n’est pas dans le bon bloc, alors on retourne simplement le bloc original non modifié : dans ce cas, notre HOC ne sert à rien.
Mais si on est dans le bon bloc, alors on va pouvoir ajouter notre champ à l’inspecteur. Regardons le contenu du return()
:
On observe tout d’abord qu’on retourne notre composant original, nommé BlockEdit
dans le HOC, puis on ajoute à l’inspecteur, via <InspectorControls>
.
Le SelectControl
propose les 3 options : petit, moyen et grand, et va s’occuper de l’enregistrement de l’attribut via la fonction onChange
.
Désormais, lorsqu’on sélectionnera le bloc dans l’éditeur, on devrait désormais voir notre champ select dans l’inspecteur à droite !
Hook #3 : Ajout de la classe dans le bloc dans l’éditeur
Ce troisième hook va permettre d’agir sur le bloc lorsqu’il est rendu dans l’éditeur. On va utiliser là aussi un HOC afin de pouvoir injecter notre classe sur mesure.
La première chose qu’on va faire, c’est vérifier qu’on est dans le bon bloc. C’est toujours le même code, et vous l’avez compris, mais cette vérification est nécessaire dans chaque hook.
Si on est dans le bon bloc, on va ajouter une classe et renvoyer le bloc. Pour cela on ajoutera la propriété className
dans notre Block
original. Le nom de classe va se baser sur notre valeur size
. On pourra alors avoir :
has-size-small
has-size-medium
qui est la valeur par défauthas-size-large
On va donc définir ces classes dans le fichier CSS de notre bloc :
Maintenant, dès qu’on va changer la valeur de notre champ select, le bloc se mettra à jour pour afficher la classe correspondante, par exemple has-size-large
. Dans ce cas, on devrait voir que le texte est affiché en plus gros.
Hook #4 : Ajout de la classe dans le HTML sauvegardé
Et pour finir, il faut ajouter notre classe lors de l’enregistrement HTML de notre bloc, afin qu’elle soit affichée sur le site, en front.
Ici c’est tout simple : on récupère notre attribut size
, et on génère notre nom de classe CSS.
Et voilà, tout est enfin prêt ! Notre bloc est désormais amélioré grâce aux 4 hooks. Vous avez désormais le principe général des hooks.
Découvrir d’autres filtres
On a vu 4 filtres dans ce cours, mais il en existe pas mal d’autres. Certains concernent l’éditeur et d’autres directement les blocs.
Pour les découvrir, je vous invite à aller faire un tour dans la documentation officielle de WordPress. Voici les hooks qui concernent l’éditeur :
Et voici les hooks qui concernent plutôt les blocs :
C’était une première approche des hooks de Gutenberg. Maintenant que vous connaissez le principe, vous allez pouvoir modifier en profondeur le fonctionnement des blocs et de l’éditeur, directement à partir de votre extension et sans modifier le code original.
seb
Le 25 avril 2023
Bonjour,
quand j’essaie d’ajouter des options a un bloc j’ai une erreur js que je n’arrive pas a comprendre.
Uncaught SyntaxError: Unexpected token ‘<' (at gutenberg-filters.js?ver=6.2:30:9)
Elle fait référence au qui pourtant est bien défini un peu pluys haut.
une idée ?
Maxime BJ
Le 25 avril 2023
C’est une erreur de syntaxe JS à priori. Ligne 30, colonne 9. Regarde un petit peu avant si tu as bien ouvert / fermé correctement les accolades, crochets ou guillemets !