Comme je vous en parlais dans mon article précédent, je suis enfin passé au nouvel éditeur de texte pour WordPress aussi connu sous le doux nom de Gutenberg. Cet éditeur est clairement le futur de WordPress (que cela vous plaise ou non) et sera d’ailleurs bientôt plus qu’un simple éditeur de texte. Par exemple, ce que vous connaissez encore sous le nom de Widgets seront bientôt remplacés par des blocs Gutenberg… et ce n’est que le début!

Étant donné que Gutenberg est là pour durer, autant s’y habituer le plus vite possible et se faciliter un peu la vie. Aujourd’hui je vais donc vous montrer comment vous pouvez créer assez facilement des blocs Gutenberg personnalisés pour par exemple créer des boxes Infos, une table des matières ou tout autre élément dont vous pourriez avoir besoin régulièrement dans vos articles.

Pourquoi créer des blocs Gutenberg personnalisés?

Je vous vois déjà venir! Vous allez peut-être me dire:

Mais il existe déjà plein de plugins de blocs pour Gutenberg!

css js loading speed

Et c’est vrai! Il y a aujourd’hui beaucoup de plugins qui ajoutent tout un tas de blocs à Gutenberg (comme des FAQ, boutons, tables des matières, info box, tableaux de prix etc…). Le principal problème de ces plugins, c’est qu’en général vous n’allez peut-être utiliser que 10% des blocs supplémentaires que ces plugins mettent à votre disposition. Ce qui fait que vous allez ajouter sur toutes vos pages de la complexité CSS et JS inutile qui va ralentir la vitesse de chargement de votre site.

Donc pour moi les principales raisons de créer des blocs Gutenberg personnalisé sont les suivantes:

  • Pour ajouter uniquement les blocs dont vous avez réellement besoin et évitez de surcharger votre site avec des CSS et JS inutiles.
  • Pour créer des blocs qui correspondent exactement à vos attentes.
  • Si vous êtes développeurs, cela vous permet de créer des éléments personnalisés facilement réutilisables par vos clients

Les différentes façons de créer des blocs Gutenberg personnalisés

Si vous voulez bien, on va directement entrer dans le vif du sujet car il existe différentes façons de créer des blocs personnalisés:

  1. Codez votre propre plugin avec la Block API pour créer votre bloc personnalisé. C’est évidemment la façon la plus compliquée car elle demande de bonnes connaissances en JS et en react.js. Personnellement je privilégie cette option seulement si le bloc que je crée pourrait être utilisé par beaucoup de monde (donc un plugin qui serait dans le répertoire WordPress) ou pour étendre les fonctionnalités des blocs existants dans Gutenberg. D’ailleurs je ne suis encore de loin pas un expert et et ce n’est pas si facile à faire lorsqu’on a peu d’expérience en Javascript. Mais je reviendrais peut-être sur ce sujet dans un prochain article mais si vous êtes curieux, vous pouvez jeter un œil à ce tuto.
  2. Utilisez un plugin qui facilite le processus de création de blocs (ou block builder). Comme beaucoup de développeurs WordPress ne sont pas des experts en Javascript (vu que WordPress est développé en PHP, c’est souvent le langage le mieux maîtrisé des développeurs WP), plusieurs plugins on vu le jour pour faciliter la création de blocs sans avoir besoin de coder en Javascript. Ces solutions sont idéales si vous avez besoin de créer des blocs personnalisés pour votre utilisation personnelle sur votre site ou pour le thème d’un client.

Vous l’aurez donc compris, dans cet article on va s’intéresser à la deuxième solution qui va nous permettre de créer des blocs sur mesure facilement (pratiquement sans avoir à écrire une seule ligne de code).

Les plugins pour créer des blocs Gutenberg personnalisés

A ma connaissance, il existe 3 plugins qui permettent de créer plus facilement des blocs pour Gutenberg:

block builder wp plugin
  • Advanced Custom Fields: C’est un des plugins les plus populaires pour WordPress (plus d’un million d’installations quand même). Il permet à la base d’ajouter des champs personnalisés un peu partout sur votre site et sa version premium vous permet aussi de créer des blocs Gutenberg customisés.
  • Genesis Custom Blocks (anciennement Block lab): Block lab était le premier plugins à s’attaquer à ce problème et a depuis été racheté par WP Engine puis renommé Genesis Custom blocks. La majorité des fonctionnalités du plugins sont encore gratuites mais certaines ont été restreintes aux utilisateurs de Genesis pro.
  • Lazy blocks: Ce plugin est le dernier constructeur de blocs encore complètement gratuit et permet de faire tout ce que les 2 plugins cités ci-dessus font dans leur version payante. C’est pour ça que j’ai choisi de tester celui-ci en premier (et vous allez voir, le tester c’est l’adopter).

Donc ci-dessous on va s’intéresser au plugin Lazy blocks et je vais d’abord vous montrer comment créer un bloc simple comme une Infobox que vous pourriez utiliser dans vos articles. Je vous montrerai ensuite comment créer un bloc plus complexe pour créer automatiquement une table des matières sur la bases des titres de votre article ou page.

Créer un bloc Infobox avec le plugin Lazy blocks

Pour commencer il vous faut évidemment installer le plugin Lazy blocks. Une fois activé, cliquez dans le menu de gauche sur Lazy blocks -> add new pour commencer à créer votre premier bloc. Vous arriverez alors sur la page suivante:

Menu de création de blocs du plugin Lazy blocks

Note: la documentation du plugin Lazy blocks est bien faite et très complète. Je vous redirigerai régulièrement sur certaine page de la doc

Il y a 3 parties principales:

  • Les “Controls” (ou contrôleurs): Les contrôleurs sont tous les éléments que vous pouvez ajouter à votre bloc. Vous pourriez ajouter une zone de texte pour le titre ou une description, une image, un bouton et beaucoup d’autres choses. Vous verrez qu’avec tous les contrôleurs à votre disposition, vous ne serez limité que par votre imagination pour créer vos blocs. Vous trouverez la liste de tous les contrôleurs disponibles par ici
  • Le “Code”: C’est ici que vous pourrez définir le code HTML qui sera affiché par les contrôleurs dans vos articles et/ou l’éditeur de texte. Il y a 3 façons de définir l’affichage du code (HTML+handlebars, PHP ou directement écrire le code dans votre thème) mais j’expliquerai tout ça plus bas.
  • Réglages du bloc ou des contrôleurs: Dans le menu de droite, vous pourrez définir le titre de votre bloc, sa descriptions, son icon, ou il sera affiché dans le menu Gutenberg… Si vous sélectionnez un contrôleur, vous pourrez aussi définir ses différents attributs dans le menu de droite.

Maintenant que vous comprenez les bases, revenons à l’exemple de notre boxe info. Dans cette boxe nous aimerions pouvoir ajouter un titre si désiré et du contenu qui doit être flexible (paragraphe, images, listes, boutons etc…). Nous allons donc définir les contrôleurs suivants:

les 2 contrôleurs de notre bloc Infobox
  • un contrôleur “title” (titre): Un simple contrôleur de “type” texte pour pouvoir définir le titre de l’infoboxe. Notez bien que l’attribut “Name” du contrôleur est important puisque c’est celui qui sera utilisé ensuite dans la partie code.
  • un contrôleur “content” (contenu): Pour ce contrôleur on va choisir le “type” très pratique “Inner Blocks”. Il permet d’ajouter n’importe quel sorte de bloc Gutenberg à l’intérieur de notre Infoboxe. Cela nous permettra d’ajouter facilement, du texte, une image, des boutons et j’en passe…

Maintenant que nous avons définis nos contrôleurs, passons à la partie un peu plus compliquée du Code qui va nous permettre d’afficher notre infoboxe dans notre article et/ou l’éditeur de texte. Comme je le disais plus haut, Lazy Blocks nous donne trois façon d’afficher le code de notre bloc (les deux premières en écrivant le code directement dans lazy blocks et la dernière en modifiant les fichiers du thème):

HTML + Handlebars: Handlebars est ce qu’on appelle un langage de “templating” qui facilite l’écriture de template HTML. Plus simplement dit, il permet d’ajouter facilement des variables dans du code HTML. Ne vous inquiétez pas, vous allez vite comprendre avec l’exemple de notre Infobox:

<div class="infobox">
    {{#if title}}
        <div class="infobox-title">{{title}}</div>
    {{/if}}
    {{{content}}}
</div>

Vous l’aurez certainement compris en lisant ces quelques lignes de code ci-dessus, il suffit d’ajouter l’attribut “Name” de votre contrôleur entre 2 {{ }} pour afficher les valeurs que vous aurez définie dans votre Infobox. Ici donc on insère dans une <div class="infobox"> </div> un titre seulement s’il est défini (c’est pour ça qu’il y a le {{#if title}}) ainsi que le contenu

PHP: Même si la syntaxe est moins élégante qu’avec Handlebars, vous pouvez écrire votre code pour l’infobox directement en PHP. Pour l’exemple de notre Infobox ça donnerait ça:

<div class="infobox">
    <?php
    if(!empty($attributes['title'])) {
    ?>
        <div class="infobox-title">
            <?php echo esc_html( $attributes['title'] ); ?>
        </div>
    <?php
    }
    ?>
    <?php echo $attributes['content']; ?>
</div>

Vous voyez donc qu’en PHP la syntaxe est un peu plus verbeuse et que les valeurs de l’infobox sont contenue dans la variable $attributes et donc pour le titre vous devrez afficher $attributes['title'] et pour le contenu $attributes['content'].

Theme Template: Enfin vous pouvez ajouter ce code directement dans votre thème. Lorsque vous choisissez cette option, Lazy blocks vous indique un dossier dans lequel vous devez créer un fichier block.php qui contient le code de votre bloc qui est exactement le même que pour l’option PHP. C’est la méthode que j’utilise pour tous les thèmes des sites que je développe car je préfère avoir le code des blocs directement dans le thème plutôt que de les sauver dans la base de donnée (plus d’infos sur cette méthode par ici). Voici donc mon fichier block.php:

<?php
/**
 * Infobox block
 *
 * @var  array  $attributes Block attributes.
 * @var  array  $block Block data.
 * @var  string $context Preview context [editor,frontend].
 */
?>
<div class="infobox">
    <?php
    if(!empty($attributes['title'])) {
    ?>
        <div class="infobox-title">
            <?php echo esc_html( $attributes['title'] ); ?>
        </div>
    <?php
    }
    ?>
    <?php echo $attributes['content']; ?>
</div>

Donc une fois que vous aurez choisi une de ces 3 méthodes, éditez un article existant ou créez un nouvel article et ajoutez un bloc. Vous devriez voir votre nouveau bloc Infobox avec l’icon que vous avez défini, à l’endroit ou vous l’avez défini dans le menu Gutenberg.

Nous allons ajouter le bloc Infobox à notre article. Sous “Title” vous pouvez rentrer le titre de votre Infobox et sous “Content”, vous pouvez insérer n’importe quel bloc que vous souhaitez comme par exemple ci-dessous une image, 2 paragraphes et 1 lien:

Exemple de notre Infobox avec un titre et le contenu qui a une image à droite, 2 paragraphes et 1 lien.

Et voilà ce que donne cette Infobox sur Novo-media:

Un test de titre

une description d’image qui va se trouver autour de l’image flottante à droite

un deuxième paragraphe que j’ajoute à l’infobox

Un exemple de lien

le code HTML généré par notre bloc personalisé est le suivant comme définit dans notre code:

<div class="infobox">
    <div class="infobox-title">Un test de titre</div>
    <div class="wp-block-image">
        <figure class="alignright size-medium">
            <img src="https://novo-media.ch/app/uploads/2020/05/ewww-premium-plus-png-image-compression-300x197.jpg" alt="" class="wp-image-4369 ls-is-cached lazyloaded" srcset="https://novo-media.ch/app/uploads/2020/05/ewww-premium-plus-png-image-compression-300x197.jpg 300w, https://novo-media.ch/app/uploads/2020/05/ewww-premium-plus-png-image-compression-1024x672.jpg 1024w, https://novo-media.ch/app/uploads/2020/05/ewww-premium-plus-png-image-compression-768x504.jpg 768w, https://novo-media.ch/app/uploads/2020/05/ewww-premium-plus-png-image-compression-1536x1008.jpg 1536w, https://novo-media.ch/app/uploads/2020/05/ewww-premium-plus-png-image-compression.jpg 1600w" sizes="(min-width: 600px) 30vw, 100vw" width="300" height="197">
        </figure>
    </div>
    <p>une description d’image qui va se trouver autour de l’image flottante à droite</p>
    <p>un deuxième paragraphe que j’ajoute à l’infobox</p>
    <p><a href="https://novo-media.ch/?swcfpc=1" class="button gradient">Un exemple de lien</a></p>
</div>

Quelques remarques supplémentaires

Affichage dans l’éditeur: Vous pouvez aussi contrôler si vous le souhaitez le code qui est affiché dans l’éditeur Gutenberg. Personnellement, je préfère ne pas m’embêter avec ça et je définis toujours “Never” sous “Show block preview in editor”. Mais peut-être que vous voudriez être un poil plus perfectionniste que mois si vous développez un thème pour un client. Si c’est le cas, vous pouvez simplement choisir “Always” et définir le code qui doit être affiché dans Gutenberg sous “Editor”. Si vous utilisez la méthode “Theme template”, vous pouvez simplement créer en plus de block.php un autre fichier editor.php.

Le style CSS de l’infobox: Évidemment il ne suffit pas de créer le HTML de l’Infobox, il s’agit aussi de lui donner un style avec un peu de CSS. Si vous savez modifier le CSS de votre thème, vous pouvez ajouter directement quelques lignes de code dans le fichier style.css du thème. Sinon en général sous le menu apparence->personnaliser il y a un menu tout au font pour ajouter du CSS personnalisé sans modifier le thème de votre site. Voici par exemple quelques règles CSS que vous pourriez ajouter:

.infobox {
  background-color: #000;
  padding: 20px;
  margin-top: 10px;
  margin-bottom: 10px;
}

.infobox .infobox-title {
  text-align: center;
  padding: 10px;
  font-size: 25px;
  font-weight: bold;
}

Vous pourriez évidemment ajouter plus de CSS pour obtenir exactement le résultat que vous désirez.

Créer un bloc Table des Matières avec le plugin Lazy blocks

Maintenant que vous voyez comment créer des blocs simples pour personnaliser le design de vos articles, je vais vous montrer un exemple plus poussé. On va coder un bloc Table des matières qui va créer automatiquement une table des matières en fonction de vos titres.

Note: je ne vais pas revenir en détails sur le fonctionnement du plugin Lazy blocks cette fois. Je pars du principe que vous avez compris les contrôleurs, le code et les réglages.

Les Contrôleurs: Pour ce bloc table des matières on va avoir besoin de 4 contrôleurs (1 text pour définir le titre de la table des matières et 3 checkboxs pour choisir quels niveaux de titres on aimerait voir apparaître dans la table des matières). Voici ce que ça donne:

les contrôleurs de notre bloc table des matières

Le Code: Pour ce bloc plus compliqué, vous allez devoir utiliser la méthode “Theme template” ou “PHP” car il y a plus de code à créer cette fois-ci. Voici le code de mon fichier block.php:

<?php
/**
 * Table of content block
 *
 * @var  array  $attributes Block attributes.
 * @var  array  $block Block data.
 * @var  string $context Preview context [editor,frontend].
 */

$headings = ['h2'=>$attributes['h2'], 'h3'=>$attributes['h3'], 'h4'=>$attributes['h4']];

$allowed_headings = [];

//fill the allowed headings array based on the checkboxes
foreach ( $headings as $key => $value ) {
    if($value) {
        $allowed_headings[]=$key;
    }
}

//display the table of content
?>

<div class="toc">
    <div class="toc-title"><?php echo esc_html( $attributes['title'] ); ?></div>
    <?php echo novomedia_table_of_contents($allowed_headings); ?>
</div>

<?php
//update ids of title tags
add_filter(
    'the_content',
    function( $content ) use ( $allowed_headings ) {
        return novomedia_update_title_ids( $content, $allowed_headings );
    },
    10
);
?>

Le fonctionnement n’est pas si compliqué. On regarde d’abord quels niveaux de titres doivent être inclus dans la table des matières en fonction des 3 checkboxes (en les mettant dans le tableau $allowed_headings).

Ensuite on affiche la table des matières, avec le titre puis son contenu qui est créé par la fonction novomedia_table_of_contents() (je reviens sur cette fonction tout de suite).

Et enfin on doit encore s’assurer d’ajouter des ids (ou ancres) aux titres H2, H3 ou H4 si ces ids ne sont pas déjà définies. C’est ici la fonction novomedia_update_title_ids() qui va être appelée grâce au filtre 'the_content'.

Détaillons maintenant la fonction qui crée la liste en fonction des titres pour afficher la table des matières:

function novomedia_table_of_contents($allowed_headings) {
    global $post;
    $toc = '';
    $hcount = 0;

    $dom = new DOMDocument();
    $dom->loadHTML( mb_convert_encoding( $post->post_content, 'HTML-ENTITIES', 'UTF-8' ) );
    $elements = $dom->getElementsByTagName('*');
    foreach($elements as $child){
        if(in_array($child->nodeName, $allowed_headings) ) {
            $hcount = $hcount + 1;

            // create nested list with table of content
            // set levels
            if ($child->nodeName == 'h2') {
                $level = 1;
            }
            elseif ($child->nodeName == 'h3') {
                $level = 2;
            }
            elseif ($child->nodeName == 'h4') {
                $level = 3;
            }

            //if the id is not set, use title slug
            $title_id = $child->getAttribute('id');
            if(empty($title_id)){
                $slug = sanitize_title($child->nodeValue);
                $title_id = $slug
                ;
            }

            // open the list
            if($hcount == 1) {
                $toc .= '<ol><li>';
                if($child->nodeName == 'h2') {
                    $toc .= '<a href="#'.$title_id.'">'.$child->nodeValue.'</a>';
                    $current_level = $level;
                }
            }
            else {
                if($level - $current_level == 0) {
                    $toc .= '</li><li><a href="#'.$title_id.'">'.$child->nodeValue.'</a>';
                    $current_level = $level;
                }
                elseif($level - $current_level == 1) {
                    $toc .= '<ol><li><a href="#'.$title_id.'">'.$child->nodeValue.'</a>';
                    $current_level = $level;
                }
                elseif($level - $current_level == -1) {
                    $toc .= '</li></ol><li><a href="#'.$title_id.'">'.$child->nodeValue.'</a>';
                    $current_level = $level;
                }
            }
        }
    }
    if(!empty($toc)){
        $toc .= '</ol>';
    }

    return $toc;
}

Cette fonction va créer une liste imbriquée (nested list) contenant des liens vers les titres qui doivent être intégrés à la table des matières (H2, H3 et/ou H4). Si les titres n’ont pas d’id définie, c’est le slug du titre qui est choisi comme ancre.

Il nous reste ensuite à mettre à jour les ancres des titres dans le contenu de l’article à l’aide de la 2ème fonction qui est appelée avec le filtre 'the_content':

function novomedia_update_title_ids($content, $allowed_headings) {

    $dom = new DOMDocument();
    $dom->loadHTML( mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' ) );
    $elements = $dom->getElementsByTagName('*');
    foreach($elements as $child){
        if(in_array($child->nodeName, $allowed_headings) ) {
            // if id is empty, set it to title slug
            if(empty($child->getAttribute('id'))){
                $slug = sanitize_title($child->nodeValue);
                $child->setAttribute('id', $slug);
            }
        }
    }
    return $dom->saveHTML();
}

Rien de bien compliqué ici. On filtre dans le contenu de l’article tous les titres qui doivent être ajouté à la table des matières. Si l’id (ou l’ancre) du titre n’est pas définie, on la définis avec le slug du titre.

Une fois que vous avez fait tout ça, vous aurez un nouveau bloc “table of content” disponible dans Gutenberg. Il vous suffira de définir le titre de la table des matières et les niveaux de titre que vous voulez inclure et la table des matières sera créées automatiquement. C’est d’ailleurs avec ce bloc que la table des matières en début d’article a été créée.

Notre bloc table des matières qui inclut tous les titres H2 et H3 de l’article

Voilà c’est tout pour aujourd’hui. Vous savez maintenant comment créer des blocs personnalisés avec le plugin Lazy blocks. J’espère que les exemples que je vous ai donné vous aideront à créer vos premiers blocs et à imaginer le genre de blocs que vous pourriez créer pour votre site.

Et comme d’habitude, si vous avez des questions, n’hésitez pas à laisser un commentaire ci-dessous. Je vous répondrai avec plaisir!

Epingler cet article

Benoit Luisier

Développeur Web autodidacte et passionné de voyage, je partage avec vous sur Novo-Media mes conseils et astuces sur les côtés plus "techniques" de thématiques comme le développement web, Wordpress, l'optimisation ou encore le SEO. Je suis également le créateur du plugin wordpress de cartographie Novo-Map.

Newsletter: Nos derniers articles dans votre boîte mail

Rejoignez la communauté maintenant et recevez tous nos articles directement dans votre boîte mail! 0% Spam garanti !

Vous avez une question???

Si ça concerne directement cet article, laissez nous un commentaire ci-dessous, sinon n'hésitez pas à entamer une discussion sur le forum!

Interactions du lecteur

Commentaires

  1. Laurent dit

    Je me mets à Gutenberg (avec quelques trains de retard !) et je viens donc de jouer un peu avec Genesis Custom Blocks et Lazy Blocks en suivant tes bons conseils.
    Lazy Blocks et vraiment préférable en effet, car en plus des avantages que tu cites, le contenu des blocs Lazy Blocks est statique contrairement au contenu des blocs de Genesis Custom Blocks. Ça importe peu si c’est des petits blocs avec peu de texte, mais si ça n’est pas le cas et que tu utilises Yoast pour le SEO (d’autres plugins SEO semblent avoir le même problème), Yoast ne voit pas le texte contenu dans les blocs dynamiques, ce qui est un peu gênant. Le bug est décrit ici https://github.com/Yoast/wordpress-seo/issues/13235
    Et cerise sur le gâteau, Lazy Blocks permet un export des blocs alors que celui de Genesis Custom Blocks ne fonctionne plus.
    Bref, ça ne fait que confirmer ton choix 🙂

    • Benoit Luisier dit

      Salut Laurent,

      Tiens c’est marrant que tu passes par ici alors que je me remet justement aujourd’hui à écrire 2-3 articles sur Novo-media 😉 (Notamment parce que j’ai développé un nouveau site avec Generatepress à la place de Genesis et que j’ai des choses à partager à ce sujet par ici).

      Ahah mieux vaut tard que jamais pour Gutenberg… au moins, tu n’as pas eu besoin de batailler avec les bugs du début. Maintenant tu as un super éditeur de blocs qui fonctionne nickel et tu devrais apprécier. Et merci pour ton retour! Ca fait une raison de moins d’hésiter alors… Même si j’ai vu que Lazy Blocks avait une version pro maintenant aussi (bien que la version gratuite semble toujours aussi complète). Et puis, les 2 autres plugins sont aussi la propriété de WP-Engine maintenant et depuis ces acquisitions (et celle de Genesis aussi), j’ai l’impression qu’il y a moins de Maj qu’avant… j’ai pas eu de problème en particulier (avec Genesis que j’utilise toujours) mais je constate juste que c’est un peu moins dynamique qu’avant.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *