Appliquer un filtre au portfolio de Divi à l'ouverture de la page

Appliquer un filtre au portfolio de Divi à l’ouverture de la page


Imaginez que vous utilisez le thème WordPress Divi, vous avez ajouté un portfolio filtrable pour afficher vos réalisations : sites vitrines, shops en lignes et logos. Le top. Sur l’une de vos pages, vous aimeriez ajouter un lien vers vos réalisations de logos. Comment faire pour passer un paramètre filtrant le portfolio Divi au chargement d’une page ?

Il n’y a malheureusement pas de solution toute faite pour ce problème somme toute assez banal. Par défaut le portfolio de Divi ne dispose pas de cette fonctionnalité.

Comment faire alors ? Il faudra taper dans le code. Mais ne vous inquiétez pas, même si vous êtes un néophyte, vous devriez pouvoir vous débrouiller avec cet article. Le principe est le suivant :

  • Copier le code du module de portfolio filtrable directement dans votre thème enfant
  • Modifier le code du module de portfolio en tenant compte d’un paramètre passé dans l’URL pour le filtrer au chargement de la page
  • Le référencer dans le fichier functions.php de votre thème enfant, afin de l’utiliser à la place du module par défaut

Avant d’entrer dans le vif du sujet, un peu de contexte.

C’est quoi le thème Divi ?

Le thème Divi est un des plus célèbre thème WordPress payant sur la planète. Proposé avec certains hébergeurs, il s’est assez vite imposé comme une référence.

Bien plus qu’un simple style visuel, Divi offre une quantité d’outils de création. Fourni par défaut avec certains hébergements, notamment Infomaniak, c’est au départ un thème payant développé par la société Elegant Themes.

Elegant Themes : Créateurs de Divi

Elegant Themes est un des mastodontes de la création de thèmes WordPress. Je travaillais déjà avec certains de leurs thèmes en 2010. Cependant, tous leurs thèmes sont payants et nécessitent un abonnement à leur plate-forme pour pouvoir être utilisés.

Pour travailler avec Divi on utilise le Visual Builder, le “constructeur visuel”, qui permet de modifier le contenu de son site directement en WISIWYGWhat You See Is What You Get : ce que vous voyez est ce que vous obtenez.

Sections, lignes et colonnes : la structure de Divi
Sections, lignes et colonnes : la structure de Divi

Divi fonctionne à l’aide de sections, contenant des lignes pouvant se séparer en plusieurs colonnes. Chaque colonne peut contenir un module. Dans Divi, tout contenu passe par un module : texte, titre d’un article, image, galerie de photos, etc.

En plus des nombreux modules de bases, il en existe également une quantité téléchargeable pour étendre encore les capacités de Divi. Et le blog d’Elegant Themes vous proposera également pas mal de solutions pour ajouter ou modifier des fonctionnalités à certains modules par le code. Mais pas celle que je vais vous présenter !

Le module de portfolio filtrable

Module de porfolio filtrable
Module de porfolio filtrable

Divi propose un module appelé Portefeuille filtrable. Il s’agit en fait d’un module de portfolio où vous pourrez filtrer l’affichage de vos travaux par catégorie. Cela permet par exemple d’afficher et filtrer vos réalisations, références ou autre. En pratique, le module de portfolio vous propose d’afficher tous les projets de votre site WordPress.

Projets WordPress

Les pré-requis

Pour pouvoir utiliser le portfolio filtrable et le code que je vais vous proposer par la suite, il faut vous assurer d’avoir :

Créé des catégories pour vos projets

Première chose à faire définir des catégories pour vos projets et les ajouter dans la vue catégorie sous le menu Projet.

Une fois dans cette vue, ajoutez simplement les catégories qui vous intéressent. À la création, prenez bien garde à définir vous même le nom du slug de votre catégorie. Ce nom sera utilisé en paramètre de l’URL lorsque vous souhaiterez créé un lien vers un filtre spécifique de votre portfolio.

Ajouter une catégorie de projet

Par exemple la catégorie Sites web aura le slug sites-web. Qui se traduira par une requête de ce type :

/projets/?slug=sites-web

Lorsque vous souhaiterez créer un lien filtrant par défaut votre portfolio sur les projets de type Sites web.

Appliquer ces catégories sur vos projets

Logique mais impératif.  Si vous avez déjà créé vos projets mais que ceux-ci n’ont aucune catégorie définie, difficile de créer un filtre fonctionnel.

Pour chaque projet allez donc définir la ou les catégories auxquelles il appartient.

Crée un thème enfant

C’est la bonne pratique par excellence dans WordPress, ne jamais modifier le thème original, toujours passer par un thème enfant héritant du code du thème de parent.

Vous ne savez pas comment créer un thème enfant ? Vous désirez plus de détails à ce sujet ? Découvrez mon générateur de thème enfant WordPress !

Vous-y trouverez toutes les explications indispensables à ce sujet et vous aurez la possibilité de créer votre thème en un clic !

Le problème

Lorsqu’on veut afficher toutes ces réalisations, aucun soucis, le portfolio de Divi est idéal. Mais si on désire proposer un lien au visiteur pour afficher une catégorie de projet spécifique, ce n’est pas possible nativement.

L’idée est qu’en passant une information en argument dans le lien vers la page de vos projets, on puisse activer un filtre spécifique directement sur la catégorie concernée. Par exemple :

/projets/?slug=sites-web

Ouvrirait notre page de références en filtrant initialement le portfolio sur la catégorie Sites web.

La solution

Le principe

Comme expliqué en préambule, il sera nécessaire d’écrire du code pour régler ce problème. L’idée sera de créer un nouveau module personnalisé à partir du code du portfolio Divi en lui ajoutant ces fonctionnalités.

1. Copier la classe du portfolio filtrable Divi dans votre thème enfant

Pour se faire, rendez-vous dans le dossier du thème Divi présent sous :

/wp-content/themes/Divi

Là vous trouverez toute la structure et le code du thème Divi. Pour trouver cette classe, naviguez dans :

/includes/builder/module/FilterablePortfolio.php

Copiez ce fichier et aller à la racine de votre thème enfant dans /wp-content/themes/[nom de votre thème enfant]. Là je vous conseil de créer un dossier pour plus de clarté, par exemple custom-modules. Collez-y votre fichier FilterablePortfolio.php.

Par convention, je vous conseil de le renommer également, par exemple CustomFilterablePortfolio. Donc voici le chemin de votre fichier copié :

[nom de votre thème enfant]/custom-modules/CustomFilterablePortfolio.php

2. Modifier la classe portfolio

Ouvrez le fichier CustomFilterablePortfolio.php pour commencer la modification. Première étape, changer le nom de la classe pour éviter les conflits. Remplacez donc le nom de la classe en tout début de code en la passant de :

<?php
class ET_Builder_Module_Filterable_Portfolio extends ET_Builder_Module_Type_PostBased {

À :

<?php
class Custom_ET_Builder_Module_Filterable_Portfolio extends ET_Builder_Module_Type_PostBased {

Une fois cette opération faite, rendez-vous en bas du document, dans la méthode render. C’est cette méthode qui s’occupera de générer le portfolio sur votre page web. Rendez-vous aux alentours de la ligne 574 sur la ligne de code :

wp_reset_postdata();

Notez que ce numéro de ligne est susceptible d’être modifié avec les futurs mises à jour du thème Divi. Sous cette ligne se trouve le code suivant :

if ( ! $posts = ob_get_clean() ) {
$posts = self::get_no_results_template();
$category_filters = '';
} else {
$categories_included = explode ( ',', $include_categories );
$terms_args = array(
'include' => $categories_included,
'orderby' => 'name',
'order' => 'ASC',
);

$terms = get_terms( 'project_category', $terms_args );

$category_filters = '<ul class="clearfix">';
$category_filters .= sprintf( '<li class="et_pb_portfolio_filter et_pb_portfolio_filter_all"><a href="#" class="active" data-category-slug="all">%1$s</a></li>',
   esc_html__( 'All', 'et_builder' )
 );

foreach ( $terms as $term ) {
$category_filters .= sprintf( '<li class="et_pb_portfolio_filter"><a href="#" data-category-slug="%1$s">%2$s</a></li>',
   esc_attr( urldecode( $term->slug ) ),
   esc_html( $term->name )
);
}

$category_filters .= '</ul>';
}

C’est au sein de ce code que nous allons appliquer nos modifications. Ne tenez pas compte de la première expression conditionnelle :

if ( ! $posts = ob_get_clean() ) {

Cette méthode générera simplement une vue Aucun résultat si elle est vrai. En gros si aucun projet à afficher n’existe.

À partir du else, ça devient intéressant :

} else {
$categories_included = explode ( ',', $include_categories );
$terms_args = array(
'include' => $categories_included,
'orderby' => 'name',
'order' => 'ASC',
);

$terms = get_terms( 'project_category', $terms_args );

$category_filters = '<ul class="clearfix">';
$category_filters .= sprintf( '<li class="et_pb_portfolio_filter et_pb_portfolio_filter_all"><a href="#" class="active" data-category-slug="all">%1$s</a></li>',
   esc_html__( 'All', 'et_builder' )
);

foreach ( $terms as $term ) {
$category_filters .= sprintf( '<li class="et_pb_portfolio_filter"><a href="#" data-category-slug="%1$s">%2$s</a></li>',
   esc_attr( urldecode( $term->slug ) ),
   esc_html( $term->name )
);
}

$category_filters .= '</ul>';
}

C’est cette partie que nous allons modifier. Ce code fait 4 choses :

  • Il commence par récupérer les catégories inclues dans le portfolio filtrable (car il est possible de ne pas toutes les afficher) à partir de la liste de catégories existantes.
  • Il crée ensuite un <ul> dans lequel il ajoutera un premier élément appelé All donc Tout. Ce premier élément est le premier filtre, il permettra d’afficher tous les projets. Vous pourrez constater que cet élément dispose du code class=”active”. Ce code est très important et permet d’indiquer quel est le filtre actif. Il s’agit donc du filtre par défaut.
  • Ensuite une boucle passe par toutes les catégories à afficher et créé un élément <li> pour chacune d’entre elle
  • Il ferme le <ul>

Ce code est ajouté à la variable $category_filters qui sera affichée par la suite lors du rendu final.

Que cherchons nous à faire avec ça ? Et bien Divi va observer, au chargement de la page, quelle catégorie possède la classe active afin de filtrer le portfolio en fonction.

Donc nous allons faire la chose suivante :

  • Regarder si une valeur pour le paramètre slug a été passé à l’URL de la page actuelle
  • Si c’est le cas nous allons regarder si cet attribut slug correspond au slug d’une des catégories
  • Si c’est le cas cette catégorie disposera de la classe active, en lieu et place de la catégorie par défaut Tout

Voici le code commenté que vous utiliserez pour remplacer le code mentionné ci-dessus :

} else {
$categories_included = explode ( ',', $include_categories );
$terms_args = array(
'include' => $categories_included,
'orderby' => 'name',
'order' => 'ASC',
);
$terms = get_terms( 'project_category', $terms_args );

// Initialise une variable $selected_slug
$selected_slug = "";
// Si un paramètre slug a été passé en paramètre, on l'enregistre dans cette variable
if (isset($_GET["slug"])) {
$selected_slug = $_GET["slug"];
}

// Comme on ne sait pas encore si la catégorie passée en paramètre est valide, on
// enregistre une variable permettant d'enregistrer cette information
$has_selected_slug = false;

// On initialise la variable $category_filters vide plutôt que de lui donner immédiatement
// le <ul> ainsi que le premier filtre "Tout". Nous ne savons pas si "Tout" sera le filtre actif
// donc ce code sera ajouté à la fin
$category_filters = '';

// Cette variable évite d'avoir à copier / coller du code dans les expressions conditionnelles
// elle contiendra la valeur 'class="active"' s'il s'agit de la catégorie active
$active_class = '';

foreach ( $terms as $term ) {

// Pour chaque catégorie, on regarde si la valeur du slug correspond au slug passé en paramètre
// On regarde également si un filtre a déjà été appliqué ou non pour éviter d'appliquer class="active"
// sur plusieurs catégories. Même si ça ne devrait pas arriver car un slug est unique.
if ($term->slug == $selected_slug  !$has_selected_slug) {
// Si c'est le cas, on enregistre la valuer dans $active_class pour l'ajouter plus bas
// Et on indique qu'une catégorie a été trouvée, donc plus besoin de chercher
$active_class = 'class="active"';
$has_selected_slug = true;
} else {

// On ajoute la variable $active_class dans la balise <li>. Rappelez-vous, cette variable peut soit
// contenir l'indication 'class="active"' soit être vide
$category_filters .= sprintf( '<li class="et_pb_portfolio_filter"><a href="#" %1$s data-category-slug="%2$s">%3$s</a></li>',
   $active_class,
   esc_attr( urldecode( $term->slug ) ),
   esc_html( $term->name )
);

// On s'assure de bien vider la variable $active_class pour éviter que la valeur
// persiste à l'itération suivante
$active_class = '';
}

// Si aucun slug n'a été passé en paramètre ou si celui-ci ne correspond à aucune catégorie
// de la liste, on passe $active_class à sa valeur active, afin de bien l'ajouter sur le filtre "Tout"
if (!$has_selected_slug) {
$active_class = 'class="active"';
}

// Et on ajoute le filtre "Tout" au début avec l'ouverture de la balise <ul>
// en ajoutant $active_class, qu'il soit vide ou non
$category_filters = sprintf( '<ul class="clearfix"><li class="et_pb_portfolio_filter et_pb_portfolio_filter_all"><a href="#" %1$s data-category-slug="all">%2$s</a></li>',
 $active_class,
 esc_html__( 'All', 'et_builder' )
) . $category_filters;

// Puis on ferme le <ul>
$category_filters .= '</ul>';
}

3. Remplacer le module de portfolio Divi avec votre module modifié

Dernière étape, actuellement votre thème enfant ne tient pas compte de votre nouveau module. Vous devez lui indiquer qu’il doit utiliser ce module modifié plutôt que celui par défaut de Divi.

Ouvrez votre fichier functions.php à la racine de votre thème enfant et ajoutez-y le code suivant. Le code est commenté est devrait se suffir à lui-même :

function divi_child_theme_setup() {
// Commence par vérifier que la class "ET_Builder_Module" existe
// Permet de s'assurer que les classes Divi ont bien été chargées
if ( ! class_exists('ET_Builder_Module') ) {
return;
}
// Récupère la class que vous avez créé dans le sous-dossier custom-modules
get_template_part( 'custom-modules/CustomFilterablePortfolio' );
// Instancie un nouvel objet de type Custom_ET_Builder_Module_Filterable_Portfolio
$cfwpm = new Custom_ET_Builder_Module_Filterable_Portfolio();
// Supprime le shortcode défini par Divi pour le portfolio
remove_shortcode( 'et_pb_filterable_portfolio' );
// Et le recréé en lui appliquant 2 paramètres :
// - L'instance de votre nouvelle classe créée au dessus
// - La méthode à appeler pour le shortcode, avec un "_" devant (convention WordPress)
add_shortcode( 'et_pb_filterable_portfolio', array($cfwpm, '_render') );
}

Votre nouveau module est prêt ! 🙂

Conclusion

En fouillant un peu, on arrive toujours à faire ce qu’on veut avec WordPress et plus spécifiquement Divi.

Le seul problème existant avec cette solution, c’est qu’en cas de mise à jour, le module de portfolio ne profitera pas des nouvelles fonctionnalités implémentés. Celui de votre thème enfant sera toujours utilisé au lieu du module de base de Divi.

Autre soucis potentiel : un changement de fond dans le code du portfolio, de Divi ou de WordPress pourrait empêcher votre nouveau module de fonctionner en cas d’update. Donc bien garder en tête qu’il s’agit d’éléments à tester en cas de mise à jour, pour éviter les mauvaises surprises.

L’avantages, c’est que cette technique peut-être reproduite. Si votre module ne fonctionne plus comme il devrait, avec la documentation donnée, vous devriez pouvoir le recréer sur la base du code du module mis à jour.



Aucun commentaire

0 commentaires

Soumettre un commentaire

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

derniers articles
de mon blog