• English
CONTACT

Bonjour à tous,

En attendant l'arrivée du "Visual Header", voici un tutoriel sur l'utilisation des hooks WordPress dans l'entête Divi afin d'y injecter des layouts construits avec le builder. Car en effet, depuis la version 3.1, Divi fournit de nombreux "crochets" dans son code.

Pour résumer, ces crochets permettent d'injecter ou de remplacer du code PHP dynamiquement à des endroits spécifiques, sans avoir à modifier les fichiers templates (modèles) du thème, donc sans se soucier des éventuelles futures mises à jour de ces fichiers.

Les hooks de l'entête Divi

Puisque aujourd'hui nous parlons d'entête, consultons le fichier header.php se trouvant à la racine du dossier Divi. Il contient notamment trois crochets très utiles qui vont nous permettre d'enrichir le header avec sections, lignes et modules.

1. Le filtre de la barre secondaire

/**
 * Filters the HTML output for the top header.
 *
 * @since ??
 *
 * @param string $top_header
 */
echo apply_filters( 'et_html_top_header', $top_header );

Un crochet WordPress de type "filtre" permet de filtrer une chaîne de caractères. Dans ce cas précis, la chaîne représente le code HTML généré pour la barre supérieure de l'entête, affichant classiquement téléphone, adresse e-mail et menu secondaire.

Je ne le cache pas, je n'aime pas du tout l'aspect de cette barre, et si je dois l'utiliser, je la défigure directement avec du CSS. Désormais, nous allons pouvoir la remplacer complètement par un layout personnalisé, construit avec le builder, et sauvegardé en bibliothèque.

Attention, ce filtre ne concerne que les entêtes de type "Défaut", "Centré" et "Logo inline centré". Il n'est pas applicable aux entêtes "Slide in" et "Plein écran".

2. Le filtre de la barre de navigation (y compris logo)

/**
 * Filters the HTML output for the main header.
 *
 * @since ??
 *
 * @param string $main_header
 */
echo apply_filters( 'et_html_main_header', $main_header );

Même principe que pour le filtre précédent, mais celui-ci s'applique sur le code HTML associé à la barre de navigation, incluant le logo, qu'il soit centré au-dessus ou sur la même ligne.

Je n'utiliserai pas ce filtre dans cet article car je conserve la barre de menu. De plus le fonctionnement est exactement le même que pour la barre secondaire.

Comme le précédent, ce filtre ne concerne que les entêtes de type "Défaut", "Centré" et "Logo inline centré". Il n'est pas applicable aux entêtes "Slide in" et "Plein écran".

3. L'action du haut de page

/**
 * Fires after the header, before the main content is output.
 *
 * @since ??
 */
do_action( 'et_before_main_content' );

Un crochet de type "action" fonctionne comme un filtre, sauf qu'au lieu de filtrer une chaîne, il insère un morceau de code à un endroit donné. Ici, le code spécifié est injecté après le menu de l'entête, juste avant le contenu principal de la page.

Modification de l'entête

La personnalisation de l'entête que je vous présente ici se compose de deux parties indépendantes :

  • l'insertion d'un layout à la place de la barre secondaire,
  • l'insertion d'un layout sous la barre de navigation, avant le contenu de la page proprement dit.

Je ne modifie pas la barre de navigation car je souhaite conserver le menu, mais je cache le logo via l'option associée dans le personnaliseur du thème, car je vais l'ajouter dans la partie supérieure.

Remplacement de la barre secondaire

Attention prérequis : Pour utiliser ce filtre, il faut au préalable activer la barre secondaire sur votre site. Pour cela, le plus simple est d'activer l'affichage des réseaux sociaux via le personnaliseur de thème (Entête et navigation / Éléments de l'entête). Pas d'inquiétude cependant, la barre sera complètement remplacée par votre entête personnalisé.

Une fois la top bar activée, pour effectuer la substitution, il faut d'abord créer le layout dans la bibliothèque, soit en le créant directement via le bouton "Add New" de la page Bibliothèque Divi, soit en le sauvegardant à partir d'une autre page créée avec le builder. Quelque soit la méthode, on obtient au final notre layout, ici :

Divi header builder top

De retour sur la page bibliothèque, on consulte les infos du modèle créé (cliquer sur l'option "Modification rapide" du modèle) :

Divi header builder top infos

On peut maintenant ajouter un filtre à notre crochet, à l'aide de la fonction add_filter() de l'API WordPress. Ce filtre sera chargé de remplacer le code HTML de la barre secondaire (transmis en paramètre mais pas spécifié ici puisque inuitilisé) par celui du modèle créé, en utilisant cette fois la fonction do_shortcode() pour générer le code HTML du modèle.

Remarque pour les devs : Dans le cas général, un filtre pourra effectuer toutes sortes de substitutions ou traitements sur la chaîne en entrée, qu'il faudra bien sûr spécifier en paramètre de la fonction add_filter() afin de la récupérer. Ici, c'est moins subtil, on remplace tout !

Code à ajouter dans le fichier functions.php de votre thème enfant :

/* Remplacement barre supérieure */
add_filter( 'et_html_top_header', 'top_header_layout' );
function top_header_layout() {
  $query = new WP_Query( array(
    'post_type' => 'et_pb_layout',
    'post_name__in' => array('top-header')
  ));
  return do_shortcode('[et_pb_section global_module="' . $query->posts[0]->ID . '"]
                       [/et_pb_section]');
}

Dans ce code, on effectue une recherche en base de données pour trouver l'ID interne (celui du post WordPress) du modèle à injecter, à partir de son identifiant dans la bibliothèque Divi, ici 'top-header' (Cf. capture ci-dessus).

Insertion après la barre de navigation

Comme pour le filtre de la barre secondaire, nous créons d'abord le modèle. Ici, ce sera juste un module menu dans une section pleine largeur :

Header Builder Bottom

Le lien "Modification rapide" du layout affiche :

Header Builder Bottom infos

Nous utiliserons donc cette fois le slug 'after-menu' pour identifier le modèle à injecter, et la fonction add_action() pour insérer le code (l'action) à sa place.

Code à ajouter dans le fichier functions.php de votre thème enfant :

/* Insertion après menu */
add_action( 'et_before_main_content', 'before_content_layout' );
 function before_content_layout() {
   $query = new WP_Query( array(
     'post_type' => 'et_pb_layout',
     'post_name__in' => array('after-menu')
  ));
  echo do_shortcode('[et_pb_section global_module="' . $query->posts[0]->ID . '"]
                     [/et_pb_section]');
}

Remarque pour les devs : Vous pouvez voir dans ce code que la fonction "action" ne retourne pas une chaîne comme pour le filtre. C'est normal car ce n'est pas une substitution de chaîne mais un code directement exécutable (une véritable action). Et dans ce cas on écrit directement dans le fichier HTML le code généré par le shortcode avec la directive echo.

Alternative avec la version plugin

Si vous préférez passer par un plugin, il suffit de prendre les deux extraits de code ci-dessus et de leur ajouter un entête dédié :

<?php
/**
 * Plugin Name: Divi Builder Header
 * Plugin URI: https://pavenum.com/blog/
 * Description: Personnalisation du haut de page Divi.
 * Version: 1.0
 * Author: Yan Thiaudière
 * Author URI: https://pavenum.com
 * License: Free
 */

/* Remplacement barre supérieure */
add_filter( 'et_html_top_header', 'top_header_layout' );
function top_header_layout() {
  $query = new WP_Query( array(
    'post_type' => 'et_pb_layout',
    'post_name__in' => array('top-header')
  ));
  return do_shortcode('[et_pb_section global_module="' . $query->posts[0]->ID . '"]
                       [/et_pb_section]');
}

/* Insertion après menu */
add_action( 'et_before_main_content', 'before_content_layout' );
function before_content_layout() {
  $query = new WP_Query( array(
    'post_type' => 'et_pb_layout',
    'post_name__in' => array('after-menu')
  ));
  echo do_shortcode('[et_pb_section global_module="' . $query->posts[0]->ID . '"]
                     [/et_pb_section]');
}

Vous n'aurez plus qu'à sauvegarder le code dans un fichier divi-header-builder.php et le "zipper" pour obtenir votre plugin prêt à l'emploi.

Alternative pour les psychopathes des performances

Vous avez constaté que j'utilisais une recherche en base de données pour récupérer l'ID des modèles à injecter, à partir de leur identifiant dans la bibliothèque (slug). Je procède de cette façon pour deux raisons :

  • par pur confort, car ainsi je peux copier/coller mes bouts de code sur n'importe quel site et créer les modèles associés en bibliothèque sans me soucier de leur ID (qu'il faudrait sinon reporter dans le code pour chaque site) ;
  • c'est indispensable pour la version plugin, puisque dans ce cas il est impossible de spécifier l'ID dans le code (les modèles sont indéfinis).

Si toutefois vous souhaitez optimiser les injections présentées dans cette article, vous pouvez supprimer la recherche en BDD et utiliser directement l'ID de chaque modèle, que vous trouverez dans la barre d'adresse sur leur page d'édition respective.

Les deux codes précédents deviennent alors, avec un ID égal à 999999 :

/* Remplacement barre supérieure */
add_filter( 'et_html_top_header', 'top_header_layout' );
function top_header_layout() {
  return do_shortcode('[et_pb_section global_module=99999][/et_pb_section]');
}

et

/* Insertion après menu */
add_action( 'et_before_main_content', 'before_content_layout' );
function before_content_layout() {
  echo do_shortcode('[et_pb_section global_module=99999][/et_pb_section]');
}

Le cas du header "fixe"

Si vous utilisez une barre de navigation fixe (qui reste en haut de l'écran avec le défilement), vous constaterez que le layout injecté dans la barre secondaire avec le code précédent se retrouve sous la barre de menu, et qu'il défile avec le reste de la page.

Pour remédier à ce problème, il suffit d'ajouter l'identifiant CSS '#top-header' à la section associée au layout.

Remarque : Dans ce cas, vous aurez surement un peu de CSS à écrire pour adapter le style de votre contenu texte, car l'ajout de cet identifiant déclenche les règles CSS de la barre secondaire (notamment taille du texte et hauteur de ligne).

Conclusion

Comme vous le voyez, l'addition des hooks dans le code de Divi facilite énormément le développement ou simplement le hacking ("hooking" ?) de notre thème préféré.

Et d'après cette récente publication d'Elegant Themes sur le contenu dynamique dans Divi, il y a fort à parier que cet article sera vite rendu obsolète et que le "Visual Header" fera rapidement son apparition, via ET eux-mêmes ou des développeurs tiers.

En attendant, vous pouvez déjà préparez vos layouts... vous n'aurez plus qu'à les importer le moment venu !

17 commentaires sur cet article

  1. Bonjour,
    Merci beaucoup pour ce formidable tuto 🙂
    J'aimerai pouvoir appliquer cela pour replacer la barre de menu (avec logo), mais mes tentatives sont infructueuses.
    Ca serait tres sympa de votre part si vous me montriez le code à utiliser.
    Encore une fois, merci pour votre aide.

    1. Salut Chris,

      Si vous utilisez le filtre du paragraphe 2, ça devrait marcher.
      Par exemple :

      /* Remplacement menu principal */
      add_filter( 'et_html_main_header', 'main_header_layout' );
      function main_header_layout() {
      $query = new WP_Query( array(
      'post_type' => 'et_pb_layout',
      'post_name__in' => array('main-header')
      ));
      return do_shortcode('[et_pb_section global_module="' . $query->posts[0]->ID . '"]
      [/et_pb_section]');
      }

      Et vous appelez la section associée en bibliothèque 'main-header'.

      Bon courage 🙂

  2. Bonjour,

    Très pratique et facile à comprendre lorsque l'on débute (ce qui est mon cas) ! Merci beaucoup pour ce tutoriel détaillé qui a mis fin à mon casse-tête 🙂

    Bonne continuation,

    Joanne

  3. Vraiment Top Yan,
    croyez-vous qu'il soit possible de n'appliquer le nouveau TOP Header QUE sur la version mobile ?

    1. Salut Aurélien,
      Oui, le plus simple étant d'utiliser les options d'activation du Divi builder pour désactiver par exemple la section ajoutée.

      1. En effet, je vais tester, car le code de remplacement va supprimer ma top bar d'origine en version desktop, et je voudrai la conserver... en tout les cas ça ouvre de belles perspectives !

        1. Ah, alors dans ce cas il vaut mieux ajouter votre header au top-header plutôt que de le remplacer, et masquer l'un ou l'autre avec un media query en CSS.
          Pour ça, il faut ajouter le top header d'origine en param de la fonction pour le récupérer, et lui concaténer le votre avant de retourner l'ensemble.
          Un truc style :
          function top_header_layout( $original_top_header ) {
          ...
          return $original_top_header . do_shortcode........
          }
          Je n'ai pas testé 😉

  4. Bonjour aurélien,

    J'ai installé et activer le plugin mais je ne trouve pas le moyen de mettre mon logo en top-header ?

    Pouvez-vous m'aider ?

  5. Bonjour Yan, merci et bravo pour cette technique fort pratique !

    J'aimerais toutefois pouvoir l'implémenter avec Polylang, et ainsi avoir un header différent pour chaque langue.
    Quel serait selon vous façon la plus simple de le faire ?
    D'avance merci

    1. Merci pour votre message !

      Le plus simple je pense est de tester la langue pour conditionner l'affichage de tel ou tel header :
      if ( pll_current_language('locale') == 'FR_fr' ) {
      ......
      }
      Doc Polylang : ‘$value’ => (optional) either ‘name’ or ‘locale’ or ‘slug’, defaults to ‘slug’
      https://polylang.wordpress.com/documentation/documentation-for-developers/functions-reference/

      Maintenant, si seuls le titre et le menu changent en fonction de la langue, ce n'est même pas la peine de faire la différence car ils sont déjà dynamiques (le menu dans "Gérer les emplacements" et le titre inséré à partir du Module "Titre du post").

  6. Bonjour Yan,
    Tout d'abord un grand Merci pour ce tutto qui m'a permis de construire une vrai beau header !

    Serait-ce abuser que d'avoir le code CSS à insérer (et me dire où l'insérer) pour avoir ma mise en page d'origine sur ce header, sachant que j'ai besoin d'une barre de navigation fixe qui complique un peu les choses comme tu nous l'avais précisé ? En effet, je suis novice et ne connais rien au codage... Ca me sauverait définitivement... Encore une fois, merci !

    1. Salut Virginie,
      Je comprends que tu entends par "mise en page originale" le style du modèle que tu as créé pour l'injecter dans un header fixe, c'est bien ça ?
      Dans ce cas je ne peux pas te donner le code CSS car il dépend de ton modèle. Si c'était le même pour tout le monde, je l'aurais donné dans l'article 😉
      Pour commencer, pour éviter au maximum les conflits avec le CSS de la top bar standard, tu dois spécifier les couleurs, fontes, tailles dans le constructeur de page et éviter de laisser toutes les valeurs par défaut. Ensuite, s'il reste des problèmes de style, il faut les identifier avec l'inspecteur de code de ton navigateur et en déduire les règles CSS à écrire, qu'il faudra ajouter dans le CSS custom des options Divi (bas de première page), ou dans celui de WordPress (en bas de du personnaliseur de thème) ou dans to thème enfant.

  7. Bonjour !

    j'ai testé vos méthodes pour remplacer le menu wordpress (ou insérer une section sous le menu).
    Si le remplacement des sections fonctionne bien, le css du contenu de ma page se "supprime" partiellement... (par exemple le css d'un bouton qui saute). Même après plusieurs tentatives ce ne sont jamais les mêmes modules qui sautent, cela diffère aussi d'une page à l'autre.
    Sauriez-vous d'où cela peut venir ?

    Merci d'avance

    1. Bonjour Juliette,
      Les symptômes que vous décrivez me font plutôt penser à un problème de synchronisation des feuilles de style...
      Avez-vous vidé le cache des modules Divi (options/créateur) et votre cache navigateur ?
      Éventuellement vos plugins de cache ou d'optimisation ?
      Contactez-moi en privé si vous voulez que je jette un œil.

Répondre à Stéphane PISKORZ Annuler la réponse

Votre adresse IP ne sera pas collectée.
Vous pouvez renseigner votre prénom ou votre pseudo si vous êtes un humain ;-)