ACF Blocks avec Gutenberg et Sage

Combiner la flexibilité de Gutenberg, la simplicité d’ACF et la robustesse de Sage

Nico Prat
nicooprat
Published in
5 min readOct 22, 2018

--

Ressources :

💬 Thread d’origine sur le forum de Sage : infos, bugs et discussions
📦 Sage-acf-wp-blocks : package Composer pour Sage
📦 Timber-acf-wp-blocks : package Composer pour Timber

Gutenberg est la future révolution de WordPress qui permet enfin de “modulariser” l’édition des pages et articles : l’expérience de l’auteur est vraiment remise au cœur de WordPress. Malheureusement, celle du développeur est quelque peu mise à mal…

Par exemple, bien qu’il soit possible de rendre un bloc réutilisable, il est impossible de faire varier son contenu sans le rendre à nouveau unique (imaginez un bloc “citation” avec une certaine mise en page… mais avec toujours la même citation !). Peut-être dans une future version ?

Ensuite, pour créer un nouveau bloc de manière programmatique (hors éditeur backoffice), il faut s’accrocher : l’aperçu du travail nécessaire pour créer le moindre bloc est particulièrement décourageant. Sans parler de choix d’architecture peu intuitifs : créer un bloc “statique” aura un template React, mais un bloc “dynamique” (afficher les 5 derniers articles par exemple) aura un template PHP à l’ancienne.

Aussi, le contenu est toujours stocké en base de données au format HTML (par souci de rétro-compatibilité je suppose, mais dommage de ne pas passer à une représentation objet) ; cela dit un bloc peut également gérer certaines meta-données en JSON dans un commentaire HTML. Pire encore, les deux peuvent cohabiter, la liberté étant laissée au développeur. Confus, peu pratique et vraiment pas sexy…

Enfin, étant habitué à utiliser Sage et le moteur de template Blade, cette dualité abouti à maintenir deux types de templates, dont un avec React qui viendrait s’incruster dans la fête.

En bref, si j’étais particulièrement enthousiaste à l’idée de voir Gutenberg donner un coup de jeune à WordPress, j’ai vite déchanté après quelques présentations des dessous de la machine.

ACF Ă  la rescousse

Heureusement, une fois n’est pas coutume, Advanced Custom Fields va nous sauver la mise. La dernière version beta (5.8) propose d’assigner des groupes de champs personnalisés à des blocs : plus qu’une seule façon de gérer nos templates, pas de question à se poser quant au stockage des données, et pas de nouveau langage à apprendre ! Une fois installée vous pourrez rapidement aboutir à ce résultat :

Exemple d’un bloc Témoignage avec champs personnalisés

Si vous avez déjà utilisé ACF vous ne serez pas dépaysés puisque l’utilisation est parfaitement identique à vos habitudes. En terme de code, la marche à franchir est donc nettement plus simple qu’apprendre, entre autres, React :

Le code est ici réduit au strict minimum : déclarer un nouveau bloc, et indiquer à WordPress quel HTML il doit rendre. En l’occurrence, en incluant un fichier PHP à ce chemin : /template-paths/block/content-{$slug}.php.

Rendre la création de bloc générique

Pour éviter d’avoir à dupliquer ce code à chaque nouveau bloc créé, on va le rendre générique et se baser sur des conventions : tous les fichiers du dossier blocks sont les templates des blocs correspondants, et leurs metadonnées (name, title, category) sont gérées en commentaire (comme pour les templates personnalisés de WordPress en fait). On aura donc par exemple, pour un bloc ayant pour name “testimonial” :

D’après mes tests, seuls les champs titre et category sont nécessaires, et le champ name est déduit du nom du fichier. On peut d’ailleurs en profiter pour avoir des styles particuliers en utilisant l’identifiant unique du bloc, par exemple si vous avez créé un ACF de type couleur. Côté PHP on a plus qu’à parcourir le dossier contenant nos templates et les déclarer comme blocs personnalisés :

La création d’un nouveau bloc ne nécessite donc plus qu’une seule étape : créer un template. Ne reste qu’à lui assigner des champs personnalisés comme vous en avez l’habitude dans l’interface d’ACF.

Encore plus fort avec Blade

En bonus, l’ensemble des fonctionnalités proposées avec Blade peuvent être disponibles très facilement. À l’intérieur d’un bloc, on pourra donc, par exemple, appeler un autre composant tel que components/btn.blade.php :

La seule différence est la façon dont on doit appeler le template du bloc, cette fois avec \App\template("blocks/${slug}", ['block' => $block]) (ligne 5) :

J’en ai profité pour fusionner (ligne 4) les différentes classes qu’on peut attribuer : le nom du bloc bien sûr, mais aussi l’alignement (par défaut dans Gutenberg) et les classes additionnelles que l’auteur peut ajouter.

Conclusion

C’est encore une technique à mettre à l’épreuve du temps puisque j’ai tout juste fait ces tests, mais cela permet de rendre la création de bloc à la fois plus simple, plus souple et plus robuste en alliant trois technologies ; et ce sans apprendre de nouveau langage ou remettre en question vos connaissances de WordPress.

Seul bémol que j’ai trouvé pour l’instant, l’impossibilité de traduire les noms des blocs, puisque ceux-ci sont indiqués en commentaire. Ce n’est pas un problème dans la majorité des cas, mais ça peut être gênant si vous souhaitez partager publiquement un bloc personnalisé. Si vous avez une idée…

En tout cas, le code est très certainement améliorable, donc je suis ouvert aux propositions :)

Edit 2020

Excellente nouvelle : depuis ACF 5.9, il est possible d’utiliser les InnerBlocks de Gutenberg, c’est à dire de rendre des blocs imbriqués les uns dans les autres, ce qui multiplie encore la flexibilité de cette solution : https://www.advancedcustomfields.com/blog/acf-5-9-exciting-new-features/

Il suffit d’ajouter le support de cette fonctionnalité de cette façon :

acf_register_block_type(array(
...,
'supports' => array(
'__experimental_jsx' => true
),
));

Et de rendre cette balise spécifique (une seule par bloc, pour le moment) :

<div>
<InnerBlocks />
</div>

On peut par exemple facilement créer des blocs uniquement visuels comme des cartes qui permettent d’y imbriquer n’importe quel contenu à son tour dans Gutenberg :

--

--

Nico Prat
nicooprat
Editor for

DĂ©veloppeur & designer front-end. Freelance & fondateur de @globetrotterio