Si vous avez déjà ajouté “juste une petite ligne” dans Divi et que tout votre header s’est mis à clignoter après une mise à jour, vous avez touché du doigt le vrai sujet : l’extension propre de Divi 5 passe par des hooks, pas par des modifications directes des templates.
Le problème / Le besoin
Divi 5 (April 2026) a beaucoup progressé côté performance et architecture, mais les besoins restent les mêmes sur les sites réels : ajouter une classe sur le body, injecter un attribut sur un bouton, modifier un module existant, charger un script uniquement sur certaines pages, ou encore tracer des infos en debug sans casser l’éditeur visuel.
Le souci, c’est que beaucoup de snippets “Divi hooks” qu’on trouve en ligne sont écrits pour d’anciennes générations (Divi 3/4), utilisent des hooks obsolètes, ou font du DOM hacking (jQuery qui cherche des sélecteurs instables). Ça marche… jusqu’au prochain update.
À la fin, vous saurez mettre en place une petite “couche d’extension” propre (mini-plugin) qui exploite les hooks WordPress (fiables) et, quand c’est pertinent, les points d’entrée Divi 5 (plus spécifiques), avec des exemples concrets et testables sur WordPress 6.9.4 et PHP 8.1+.
Résumé rapide
- On évite les modifications de fichiers du thème Divi et les injections JS fragiles.
- On crée un mini-plugin (ou un MU-plugin) pour centraliser vos hooks.
- On utilise des hooks WordPress “socle” (ex :
wp_enqueue_scripts,body_class,the_content,render_block,template_redirect). - On ajoute des adaptations Divi 5 quand nécessaire (détection du builder, chargement conditionnel, compatibilité front/éditeur).
- On sécurise (capabilities, nonces, sanitization/escaping) et on garde un œil sur la performance.
Quand utiliser cette solution
- Vous voulez personnaliser Divi 5 sans thème enfant (ou avec un thème enfant minimal) et sans perdre vos changements.
- Vous devez ajouter des comportements (scripts, styles, attributs, classes, tracking) de façon conditionnelle (par page, par rôle, par type de contenu).
- Vous maintenez plusieurs sites Divi et vous cherchez une approche reproductible (un plugin interne activable partout).
- Vous avez des besoins compatibles avec l’éditeur (ne pas casser le Visual Builder / l’éditeur Divi).
Quand ne PAS utiliser cette solution
- Votre besoin est purement “mise en page” (espacements, colonnes, styles). Dans ce cas, passez par les options Divi, le Theme Builder et le CSS natif, plutôt que du PHP.
- Vous voulez “réécrire” un module Divi de fond en comble. Là, un module custom Divi 5 (ou un plugin dédié) est souvent plus propre qu’une collection de filtres.
- Vous avez un site très complexe et vous devez versionner/tester sérieusement. Préférez une approche plugin + CI (tests, linters) plutôt que des snippets collés dans un plugin de type “Code Snippets”.
Prérequis / avant de commencer
- WordPress 6.9.4 (ou plus récent) et PHP 8.1+. Si vous êtes en PHP 7.x, ne forcez pas : vous allez tomber sur des erreurs de syntaxe et des warnings.
- Divi 5 à jour. Évitez de mélanger des tutos Divi 4 avec Divi 5 sans vérifier les équivalences.
- Un environnement de test : staging, ou au minimum un backup complet (fichiers + base).
- Accès aux logs (ou
WP_DEBUG_LOG) pour voir les erreurs PHP. - Un plugin de cache peut masquer vos changements. Prévoyez de vider le cache (plugin + serveur + navigateur).
Sources utiles côté WordPress (officielles) :
- Hooks (actions & filtres) — Developer Resources
- wp_enqueue_script()
- Filtre body_class
- Filtre render_block
- Types en PHP (PHP.net)
L’approche naïve (et pourquoi l’éviter)
La version que je vois le plus souvent sur des sites Divi “qui ont grandi vite” : on ouvre header.php (ou un fichier du thème), on colle du PHP, on ajoute du JS dans “Code d’intégration” Divi, et on se dit que c’est réglé.
Exemple naïf typique
Injection de script partout, y compris dans l’éditeur, sans condition, sans versionning, sans dépendances :
<?php
// Anti-pattern : modification directe d'un fichier du thème + script inline non conditionnel
add_action('wp_footer', function () {
echo '<script>console.log("tracking");</script>';
});
?>
Pourquoi ça casse (souvent)
- Mises à jour : si vous modifiez le thème parent, vous perdez tout. Même avec un thème enfant, vous risquez des divergences.
- Performance : chargement partout, pas de cache-busting, pas de dépendances, pas de condition (mobile/desktop/page).
- Compatibilité builder : le Visual Builder charge des contextes spécifiques. Un script “global” peut casser l’édition (j’ai vu des boucles de re-render à cause d’un simple
scrolllistener). - Sécurité : sortie non échappée si vous affichez des données, absence de nonce si vous ajoutez des endpoints.
La bonne approche — tutoriel pas à pas
L’idée : créer un mini-plugin qui centralise vos hooks WordPress, et ajouter une petite couche “Divi-aware” (détection et conditions) pour éviter de charger des choses inutiles dans le builder.
Étape 1 — Créez un mini-plugin (recommandé)
Créez un dossier divi5-hooks-utiles dans wp-content/plugins/, puis un fichier divi5-hooks-utiles.php.
Pourquoi un plugin plutôt que functions.php : vous gardez vos personnalisations si vous changez de thème, et vous pouvez désactiver le tout en cas de problème (diagnostic).
Étape 2 — Ajoutez une “détection builder” pragmatique
Divi 5 évolue, et les fonctions internes peuvent changer. Je préfère une détection “dégradée” : on teste d’abord les constantes connues, puis des marqueurs de requête, et on reste permissif.
Objectif : ne pas charger certains scripts lourds quand on est dans le builder, et éviter de modifier le HTML de manière agressive pendant l’édition.
Étape 3 — Implémentez 6 hooks WordPress qui couvrent 80% des besoins
- Action
wp_enqueue_scripts: styles/scripts front, conditionnels. - Filtre
body_class: classes contextuelles (page builder, template, etc.). - Filtre
the_content: micro-ajustements (avec garde-fous). - Filtre
nav_menu_link_attributes: attributs sur liens de menu (tracking, rel, aria). - Filtre
script_loader_tag:defer/asyncproprement. - Action
template_redirect: redirections propres, sans casser l’admin.
Étape 4 — Ajoutez un exemple “Divi concret” sans hook Divi fragile
Beaucoup de demandes “Divi” sont en réalité des demandes HTML : ajouter une classe sur certains boutons, ou injecter un attribut data-*. Le plus robuste reste souvent de cibler le rendu final via the_content avec une stratégie prudente (et testable), ou via CSS/JS conditionnels.
Je vous montre une approche raisonnable : on ne parse pas tout le DOM au hasard. On limite l’impact à des pages ciblées, et on évite le builder.
Code complet
Copiez-collez ce fichier tel quel dans wp-content/plugins/divi5-hooks-utiles/divi5-hooks-utiles.php, activez le plugin, puis testez sur une page Divi.
<?php
/**
* Plugin Name: Divi 5 — Hooks utiles (actions & filtres)
* Description: Une collection de hooks WordPress utiles, pensée pour des sites sous Divi 5 (WP 6.9.4+, PHP 8.1+).
* Version: 1.0.0
* Author: Votre équipe
* Requires at least: 6.9
* Requires PHP: 8.1
*/
declare(strict_types=1);
if (!defined('ABSPATH')) {
exit;
}
final class BPCAB_Divi5_Hooks_Utiles {
private const VERSION = '1.0.0';
private const HANDLE_FRONT = 'bpcab-divi5-front';
public static function init(): void {
// Front
add_action('wp_enqueue_scripts', [__CLASS__, 'enqueue_front_assets'], 20);
add_filter('script_loader_tag', [__CLASS__, 'filter_script_loader_tag'], 10, 3);
// HTML / contenu
add_filter('body_class', [__CLASS__, 'filter_body_class'], 20, 1);
add_filter('nav_menu_link_attributes', [__CLASS__, 'filter_nav_menu_link_attributes'], 10, 4);
add_filter('the_content', [__CLASS__, 'filter_the_content'], 12);
// Routage
add_action('template_redirect', [__CLASS__, 'maybe_redirect_legacy_urls'], 1);
// Debug (désactivé par défaut, voir méthode)
// add_action('wp_footer', [__CLASS__, 'debug_footer_comment'], 999);
}
/**
* Détection pragmatique du contexte "builder".
* - On évite de dépendre d'une API interne Divi trop spécifique.
* - On privilégie une détection "soft" via constantes et paramètres.
*/
private static function is_divi_builder_context(): bool {
// Marqueurs historiques (peuvent varier selon versions/config)
if (defined('ET_BUILDER_PLUGIN_ACTIVE') && ET_BUILDER_PLUGIN_ACTIVE) {
return true;
}
// Paramètres fréquemment présents en mode builder/visual
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$et_fb = isset($_GET['et_fb']) ? sanitize_text_field(wp_unslash($_GET['et_fb'])) : '';
if ($et_fb === '1') {
return true;
}
// L'admin n'est pas le front
if (is_admin()) {
return false;
}
return false;
}
/**
* Charge des assets uniquement quand nécessaire.
* Exemple : un petit JS pour gérer des attributs data-*, ou un CSS correctif.
*/
public static function enqueue_front_assets(): void {
if (is_admin()) {
return;
}
// Exemple : ne pas charger dans le builder pour éviter les conflits d'édition.
if (self::is_divi_builder_context()) {
return;
}
// Exemple de condition : uniquement sur les pages (pas articles / archives).
if (!is_page()) {
return;
}
$src_js = plugin_dir_url(__FILE__) . 'assets/front.js';
$src_css = plugin_dir_url(__FILE__) . 'assets/front.css';
wp_enqueue_style(
self::HANDLE_FRONT,
$src_css,
[],
self::VERSION
);
wp_enqueue_script(
self::HANDLE_FRONT,
$src_js,
[],
self::VERSION,
['strategy' => 'defer'] // WP 6.3+ : support d'attributs via args
);
}
/**
* Ajoute "defer" à un script ciblé (si votre WP ne prend pas en charge 'strategy' via args,
* ce filtre reste une solution fiable).
*/
public static function filter_script_loader_tag(string $tag, string $handle, string $src): string {
if ($handle !== self::HANDLE_FRONT) {
return $tag;
}
// Si le tag contient déjà defer/async, on évite le doublon.
if (str_contains($tag, ' defer') || str_contains($tag, ' async')) {
return $tag;
}
// Injection propre : on ajoute defer avant src.
// Note : $tag est déjà un tag complet généré par WP.
$tag = str_replace(' src=', ' defer src=', $tag);
return $tag;
}
/**
* Ajoute des classes au body pour cibler CSS/JS proprement.
*/
public static function filter_body_class(array $classes): array {
if (self::is_divi_builder_context()) {
$classes[] = 'is-divi-builder';
} else {
$classes[] = 'is-divi-front';
}
if (is_page_template()) {
$classes[] = 'has-page-template';
}
// Exemple : classe si l'utilisateur est connecté (utile pour masquer des CTA).
if (is_user_logged_in()) {
$classes[] = 'is-logged-in';
}
return array_values(array_unique($classes));
}
/**
* Ajoute des attributs aux liens de menu (tracking, sécurité, accessibilité).
*/
public static function filter_nav_menu_link_attributes(array $atts, $menu_item, $args, $depth): array {
// Exemple : ajoute rel="nofollow" uniquement sur un menu spécifique via theme_location.
if (isset($args->theme_location) && $args->theme_location === 'menu-principal') {
// Ne pas écraser un rel existant, on concatène proprement.
$existing_rel = isset($atts['rel']) ? (string) $atts['rel'] : '';
$rels = array_filter(array_map('trim', explode(' ', $existing_rel)));
if (!in_array('nofollow', $rels, true)) {
$rels[] = 'nofollow';
}
$atts['rel'] = implode(' ', $rels);
// Exemple : data attribute (pour analytics) — échappé au rendu par WP.
$atts['data-menu'] = 'principal';
}
return $atts;
}
/**
* Micro-modification du contenu : ajoute un attribut data à certains boutons Divi.
* On reste prudent :
* - on cible uniquement les pages,
* - on évite le builder,
* - on n'applique pas sur les contenus trop volumineux (garde-fou).
*/
public static function filter_the_content(string $content): string {
if (!is_singular() || !is_page()) {
return $content;
}
if (self::is_divi_builder_context()) {
return $content;
}
// Garde-fou perf : évite de traiter des contenus énormes (ex: page catalogue très longue).
if (strlen($content) > 800000) { // ~800 KB
return $content;
}
// Exemple concret : repérer les boutons Divi (classe fréquente "et_pb_button")
// et ajouter data-cta="1" si absent.
// Attention : on ne fait pas un parsing HTML complet ici (DOMDocument peut être lourd),
// on applique une regex limitée sur un pattern précis.
$pattern = '/<a([^>]*class="[^"]*et_pb_button[^"]*"[^>]*)>/i';
$content = preg_replace_callback($pattern, static function (array $matches): string {
$attrs = $matches[1];
// Si data-cta existe déjà, on ne touche pas.
if (stripos($attrs, 'data-cta=') !== false) {
return '<a' . $attrs . '>';
}
// Injection : on ajoute un attribut data-cta.
return '<a' . $attrs . ' data-cta="1">';
}, $content);
return is_string($content) ? $content : $content;
}
/**
* Exemple de redirection propre : anciennes URLs vers une nouvelle page.
* - Pas de redirection en admin
* - Pas de redirection pour les utilisateurs connectés (optionnel)
* - Utilise wp_safe_redirect
*/
public static function maybe_redirect_legacy_urls(): void {
if (is_admin() || wp_doing_ajax() || wp_doing_cron()) {
return;
}
// Optionnel : éviter de gêner les éditeurs connectés.
if (is_user_logged_in() && current_user_can('edit_pages')) {
return;
}
$request_uri = isset($_SERVER['REQUEST_URI']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_URI'])) : '';
if ($request_uri === '') {
return;
}
// Exemple : /promo-2024/ devient /offres/
if (str_starts_with($request_uri, '/promo-2024')) {
$target = home_url('/offres/');
wp_safe_redirect($target, 301);
exit;
}
}
/**
* Debug non intrusif : ajoute un commentaire HTML en bas de page.
* Utile pour vérifier qu'un hook s'exécute sans polluer l'affichage.
*/
public static function debug_footer_comment(): void {
if (!current_user_can('manage_options')) {
return;
}
echo "n<!-- BPCAB Divi5 Hooks Utiles : actif | WP " . esc_html(get_bloginfo('version')) . " -->n";
}
}
BPCAB_Divi5_Hooks_Utiles::init();
Ajoutez les fichiers assets (optionnels mais pratiques)
Créez wp-content/plugins/divi5-hooks-utiles/assets/front.js :
(function () {
'use strict';
// Exemple : tracer les clics sur les boutons marqués data-cta="1"
document.addEventListener('click', function (e) {
var el = e.target;
if (!el) return;
// Si on clique sur un span à l'intérieur du lien, on remonte.
var link = el.closest ? el.closest('a[data-cta="1"]') : null;
if (!link) return;
// Ici vous brancherez votre outil analytics.
// Gardez ça léger : pas de requête bloquante, pas d'erreur si analytics absent.
if (window.console && console.debug) {
console.debug('[CTA] click', link.href);
}
}, { passive: true });
})();
Créez wp-content/plugins/divi5-hooks-utiles/assets/front.css :
/* Exemple : style léger sur les CTA marqués */
a.et_pb_button[data-cta="1"] {
outline-offset: 3px;
}
Explication du code
La logique (simple)
- On charge un CSS/JS uniquement sur les pages, uniquement sur le front, et pas dans le builder.
- On ajoute des classes au
bodypour cibler facilement vos règles CSS/JS. - On enrichit les liens de menu (ex :
rel,data-*) sans toucher aux templates. - On modifie le contenu de façon prudente pour marquer certains boutons Divi avec
data-cta. - On gère une redirection 301 propre (utile en refonte Divi).
Les hooks WordPress utilisés (précis)
wp_enqueue_scripts(action) : c’est le point d’entrée standard pour charger des assets front. Doc : wp_enqueue_scripts.script_loader_tag(filtre) : permet d’altérer le tag<script>généré. Doc : script_loader_tag.body_class(filtre) : ajoute des classes au<body>(super utile pour Divi). Doc : body_class.nav_menu_link_attributes(filtre) : modifie les attributs des liens de menus. Doc : nav_menu_link_attributes.the_content(filtre) : modifie le contenu rendu. Doc : the_content.template_redirect(action) : point idéal pour rediriger avant le rendu du template. Doc : template_redirect.
Sécurité : ce qui est fait (et pourquoi)
- Pas d’accès direct au fichier plugin (
ABSPATH). - Sanitization des paramètres
$_GETet$_SERVERviasanitize_text_field()+wp_unslash(). - Redirection via
wp_safe_redirect()(évite les open redirects). Doc : wp_safe_redirect(). - Échappement</strong dans le debug via
esc_html().
Performance : ce qui compte vraiment
- Le hook
the_contentpeut coûter cher si vous faites des regex lourdes sur des pages énormes. D’où le garde-fou de taille. - On évite de charger des assets dans le builder. C’est souvent là que les conflits arrivent (double frameworks, scripts qui interceptent des clics, etc.).
- On versionne les assets avec une constante, pour un cache-busting simple.
Variantes et cas d’usage
Variante 1 — Ajouter une classe body par “template Divi Theme Builder”
Si vous avez des templates différents selon les pages, vous voulez parfois une classe unique par ID de page pour cibler un correctif CSS.
add_filter('body_class', function (array $classes): array {
if (is_singular('page')) {
$classes[] = 'page-id-' . get_queried_object_id();
}
return $classes;
}, 30);
Ce n’est pas spécifique à Divi, mais ça vous évite de multiplier les classes custom dans l’UI.
Variante 2 — Charger un script uniquement si la page contient un shortcode
J’ai souvent vu des sites Divi charger des scripts de slider partout, alors qu’une seule page en a besoin. Si votre contenu contient un shortcode (ou un bloc), conditionnez l’enqueue.
add_action('wp_enqueue_scripts', function (): void {
if (!is_singular()) {
return;
}
$post = get_post();
if (!$post instanceof WP_Post) {
return;
}
if (!has_shortcode($post->post_content, 'mon_shortcode')) {
return;
}
wp_enqueue_script(
'mon-shortcode-js',
plugin_dir_url(__FILE__) . 'assets/shortcode.js',
[],
'1.0.0',
['strategy' => 'defer']
);
}, 20);
Doc : has_shortcode().
Variante 3 — Modifier le rendu d’un bloc Gutenberg inséré dans une page Divi
Divi et Gutenberg cohabitent souvent (FAQ en blocs, patterns, etc.). Le filtre render_block vous permet de cibler un bloc précis sans toucher au contenu brut.
add_filter('render_block', function (string $block_content, array $block): string {
if (($block['blockName'] ?? '') !== 'core/button') {
return $block_content;
}
// Ajoute un attribut data sur le HTML rendu si absent.
if (str_contains($block_content, 'data-cta=')) {
return $block_content;
}
return str_replace('<a ', '<a data-cta="1" ', $block_content);
}, 10, 2);
Doc : render_block.
Compatibilité Divi 5 / Elementor / Avada
Divi 5
- Les hooks WordPress utilisés ici restent stables, même si Divi change son rendu interne.
- Le point sensible est la détection du builder. Le snippet proposé est volontairement “soft”. Si votre site a un workflow précis, adaptez
is_divi_builder_context()(par exemple en ajoutant un header, un cookie interne, etc.). - Évitez d’injecter des scripts globaux qui interceptent les clics/drag & drop : c’est le scénario classique de “le Visual Builder ne répond plus”.
Elementor
Sur Elementor, la logique est la même : vous conditionnez l’enqueue et vous évitez d’agir dans le contexte éditeur. Elementor expose des marqueurs différents (paramètres, actions PHP). Si vous devez supporter les deux, centralisez une fonction “is_builder_context()” et ajoutez un test Elementor en plus.
Référence (code & hooks Elementor) : Elementor sur GitHub (utile pour vérifier les points d’entrée et éviter les snippets inventés).
Avada (Fusion Builder)
Avada charge aussi des assets spécifiques en mode builder. Même conseil : pas de DOM hacking global, chargez vos scripts uniquement sur les pages qui en ont besoin, et mettez des garde-fous.
Si vous utilisez des éléments Avada/shortcodes, la variante “has_shortcode” devient particulièrement rentable.
Vérifications après mise en place
- Activez le plugin, rechargez une page (front) et vérifiez que
assets/front.jsetassets/front.csssont bien chargés (DevTools > Network). - Inspectez le
<body>: vous devez voiris-divi-frontouis-divi-builder. - Sur une page avec un bouton Divi, inspectez le HTML : le lien doit avoir
data-cta="1"si la classeet_pb_buttonest présente. - Testez la redirection (ex :
/promo-2024/) en navigation privée. - Videz le cache (plugin + serveur/CDN) si vous ne voyez rien changer.
Tableau de diagnostic rapide
| Symptôme | Cause probable | Vérification | Solution |
|---|---|---|---|
| Les assets ne se chargent pas | Vous n’êtes pas sur une page, ou vous êtes en contexte builder | DevTools Network + vérifiez is_page() et et_fb=1 |
Ajustez les conditions dans enqueue_front_assets() |
| Rien ne change malgré le plugin actif | Cache (plugin/CDN/navigateur) | Désactivez temporairement le cache ou force refresh | Videz tous les caches, incrémentez VERSION |
| Erreur 500 après activation | Syntaxe PHP (point-virgule manquant) ou PHP trop ancien | Consultez wp-content/debug.log / logs serveur |
Corrigez la syntaxe, passez en PHP 8.1+ |
| Le Visual Builder se comporte mal | Script chargé dans le builder, conflit JS | Ouvrez builder, regardez la console | Renforcez is_divi_builder_context(), ne chargez pas le JS |
| Les boutons n’ont pas data-cta | Classe différente, ou contenu non filtré (module spécial) | Inspectez le HTML exact du bouton | Adaptez la regex (ou passez par CSS/JS ciblé) |
Si ça ne marche pas
- Confirmez l’emplacement : le fichier doit être dans
wp-content/plugins/divi5-hooks-utiles/divi5-hooks-utiles.php. J’ai vu des gens le coller danswp-content/plugins/divi5-hooks-utiles.php(mauvais niveau), WordPress ne le détecte pas. - Désactivez temporairement tous les plugins de snippets et minification (autoptimize, perf plugins). Les concaténations peuvent casser l’ordre des scripts.
- Activez le debug sur staging :
define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); - Regardez les logs : une erreur “Call to undefined function” arrive souvent quand on copie un code d’un ancien tuto (ou quand on a un fichier chargé trop tôt).
- Testez sans Divi Builder (front simple). Si ça marche hors builder mais pas dedans, le problème est presque toujours un script ou une condition trop large.
- Vérifiez les priorités : si un autre plugin filtre
the_contentaprès vous et “réécrit” le HTML, votre injection peut disparaître. Montez/descendez la priorité (12, 20, etc.).
Pièges et erreurs courantes
| Erreur | Cause | Solution |
|---|---|---|
| Code collé dans le mauvais fichier | Ajout dans un module Divi “Code”, ou dans le thème parent | Utilisez un mini-plugin (ou MU-plugin) et versionnez |
Parse error: syntax error |
Parenthèse/point-virgule manquant, ou copier-coller tronqué | Re-copiez le fichier complet, vérifiez les accolades |
Fatal error après update |
Snippet d’un ancien tutoriel incompatible PHP 8.1+ | Supprimez le snippet, remplacez par une version typée et testée |
| Confusion action/filtre | Utiliser add_action sur un filtre (ou inversement) |
Rappelez-vous : filtre retourne une valeur, action non |
| Le script ne se charge pas | Mauvais hook (ex : init) ou mauvais handle |
Chargez sur wp_enqueue_scripts, vérifiez le handle dans la page |
| Le CSS/JS change mais “revient en arrière” | Cache + minification + CDN | Incrémentez la version d’asset, purge CDN, purge plugin |
| Redirection en boucle | Condition trop large dans template_redirect |
Testez précisément REQUEST_URI, évitez les starts-with trop vagues |
| Le builder plante | JS global qui intercepte des événements (click/drag/scroll) | Ne chargez pas dans le builder, ou isolez le code avec conditions strictes |
Conseils sécurité, performance et maintenance
- Préférez un plugin à des snippets dispersés. Quand un site Divi a 12 endroits où du code est injecté, le dépannage devient une loterie.
- Évitez les regex “générales” sur
the_content. Si vous devez faire du HTML sérieux, envisagezDOMDocument(mais testez la perf), ou ciblez plutôt des blocs viarender_block. - Ne chargez pas jQuery “par habitude”. Divi peut déjà embarquer beaucoup de JS. Ajoutez le minimum viable.
- Redirections : utilisez
wp_safe_redirectet sortez avecexit. Ne redirigez jamais en vous basant sur une URL fournie par l’utilisateur sans validation stricte (risque d’open redirect). - Maintenance : gardez un changelog interne. Quand Divi ou WP changent, vous saurez quel hook désactiver en premier.
Pour suivre les changements côté WordPress (pratique quand un hook change de comportement) :
Ressources
- WordPress Hooks API (actions & filtres)
- wp_enqueue_script()
- Filtre body_class
- Filtre the_content
- Filtre nav_menu_link_attributes
- wp_safe_redirect()
- preg_replace_callback() (PHP.net)
FAQ
Quels sont les “hooks Divi 5” les plus fiables en 2026 ?
Pour du code durable, misez d’abord sur les hooks WordPress (ceux utilisés ici). Les hooks internes Divi existent, mais ils évoluent plus vite et sont moins documentés publiquement. Dans la pratique, 80% des personnalisations “Divi” passent très bien par wp_enqueue_scripts, body_class, the_content et des filtres d’attributs.
Pourquoi éviter de modifier les fichiers du thème Divi ?
Parce que vous perdez vos changements à la mise à jour (thème parent) ou vous créez une dette de maintenance (thème enfant avec overrides massifs). Un plugin garde vos modifications isolées et désactivables.
Est-ce que the_content est “sale” ?
Pas forcément. C’est un hook puissant, mais facile à abuser. Si vous l’utilisez, mettez des conditions strictes, un garde-fou sur la taille, et évitez les regex trop générales.
Pourquoi mon script ne se charge pas alors que le plugin est actif ?
Le cas le plus fréquent : vous testez dans le builder (et le code a volontairement un return), ou vous êtes sur un type de page exclu par is_page(). Deuxième cause : cache/minification.
Comment ajouter defer proprement sur WordPress 6.9.4 ?
Deux options : passer l’argument ['strategy' => 'defer'] à wp_enqueue_script(), et/ou utiliser script_loader_tag pour cibler un handle précis. Le filtre reste utile si un autre outil “réécrit” vos tags.
Est-ce compatible avec un site multilingue (Polylang/WPML) ?
Oui, mais attention aux redirections : adaptez les URLs cibles avec la logique du plugin multilingue (souvent via des fonctions dédiées) pour éviter de rediriger vers la mauvaise langue.
Où placer ce code si je n’ai pas accès à FTP ?
Techniquement, vous pouvez le coller dans un plugin de snippets, mais c’est moins fiable (export, ordre de chargement, rollback). Si vous n’avez pas FTP, essayez au minimum un plugin qui supporte la désactivation automatique en cas d’erreur fatale, et testez sur staging.
Comment savoir si je suis “dans le builder” Divi ?
Il n’y a pas une vérité unique. Le snippet teste des marqueurs courants (constante et paramètre et_fb=1). Sur certains setups, vous devrez ajouter vos propres signaux (ex : vérifier une route spécifique, ou un cookie). Testez en ouvrant le Visual Builder et en observant l’URL.
Puis-je transformer ça en MU-plugin ?
Oui. Placez le fichier dans wp-content/mu-plugins/. Avantage : toujours actif. Inconvénient : moins simple à désactiver pour dépanner. Sur des sites clients, je préfère un plugin standard + un process de déploiement.
Quelle est la meilleure méthode pour ajouter un attribut sur un bouton Divi ?
Si vous contrôlez le bouton (module), la meilleure méthode est souvent d’ajouter une classe/attribut via l’UI Divi. Si vous devez le faire globalement, utilisez une approche ciblée (regex limitée, ou JS conditionnel), et évitez de casser l’éditeur.