
Pour modifier un plugin WordPress sans perdre vos changements, ne touchez jamais à ses fichiers : chaque mise à jour remplace le dossier complet de l’extension et efface ce que vous y aviez écrit. Placez plutôt vos modifications à côté : dans ses réglages ou en CSS, dans une petite extension compagnon qui se branche sur les hooks (actions et filtres) prévus par l’auteur, ou dans votre thème enfant quand l’extension permet d’y surcharger ses gabarits. La copie renommée de l’extension, le fork, reste le dernier recours.
Ce guide classe ces méthodes de la plus légère à la plus lourde, avec du code prêt à adapter, puis explique comment tester vos changements en local et en préproduction. Quand je reprends un site WordPress, les extensions modifiées directement dans leurs fichiers font partie des premières choses que je vérifie : c’est la cause classique d’un correctif qui « disparaît » après une mise à jour.
Pourquoi ne jamais modifier directement les fichiers d’un plugin
Une extension installée depuis le répertoire officiel ou achetée chez un éditeur vit dans le dossier wp-content/plugins/nom-de-l-extension/. Lors d’une mise à jour, WordPress ne fusionne rien : il remplace ce dossier par la nouvelle version. Toute ligne que vous y aviez ajoutée disparaît sans avertissement, y compris lors d’une mise à jour automatique.

La tentation est alors de bloquer les mises à jour de l’extension modifiée. C’est pire : vous gardez vos changements, mais aussi les failles que les versions suivantes corrigent. Or la plupart des failles de sécurité publiées dans l’écosystème WordPress concernent des extensions, pas le cœur.
Reste l’éditeur de fichiers des extensions (Extensions > Éditeur de fichiers des extensions, ou Outils > Éditeur de fichiers des extensions avec un thème de blocs). Depuis WordPress 4.9, il tente de bloquer l’enregistrement d’un fichier qui provoquerait une erreur fatale, mais il n’a ni historique ni gestion de versions, et il ne vous protège ni d’une erreur de logique ni de la prochaine mise à jour. Mieux vaut le désactiver avec la constante DISALLOW_FILE_EDIT dans le fichier wp-config.php, qui coupe aussi l’éditeur de thèmes (voir la documentation de wp-config.php) :
define( 'DISALLOW_FILE_EDIT', true );
La règle est simple : le code de l’extension appartient à son auteur, le vôtre doit vivre ailleurs.
Personnaliser un plugin WordPress : les méthodes, de la plus légère à la plus lourde
Choisissez toujours la méthode la plus légère qui répond au besoin : plus on descend dans ce tableau, plus la modification est puissante, et plus elle demande de suivi.
| Méthode | Pour quoi faire | Survit aux mises à jour | Niveau | Point de vigilance |
|---|---|---|---|---|
| Réglages et CSS | Changer l’apparence, masquer un élément | Oui | Débutant | Le CSS masque, il ne retire rien du code chargé |
| Hooks dans une extension compagnon ou un mu-plugin | Changer un texte ou une valeur, ajouter ou retirer un comportement | Oui | Notions de PHP | Un hook peut être renommé : lire le journal des modifications |
| Surcharge de gabarit dans le thème enfant | Changer le HTML produit par l’extension | Oui, mais la copie vieillit | Notions de PHP | Comparer la copie à chaque nouvelle version |
| Retrait d’un script, d’un style ou d’un shortcode | Alléger les pages, remplacer un affichage | Oui | Notions de PHP | Ne retirer que là où l’extension ne sert pas |
| Fork (copie renommée) | Changer ce qu’aucun hook ne permet | Non : plus aucune mise à jour | Avancé | Vous devenez responsable de sa sécurité |
1. Commencer par les réglages de l’extension et le CSS
Beaucoup de demandes se règlent sans code : options de l’extension, modèles d’e-mails, réglages de ses blocs ou de ses widgets. Lisez sa documentation avant tout ; c’est aussi là que vous apprendrez si elle propose des hooks ou des gabarits surchargeables.
Pour l’apparence, le CSS suffit souvent. Avec un thème classique, ajoutez vos règles dans Apparence > Personnaliser > CSS additionnel ou dans la feuille de style de votre thème enfant ; avec un thème de blocs, l’éditeur de site propose lui aussi un CSS additionnel dans ses styles. Ciblez une classe propre à l’extension plutôt que d’empiler des !important :
/* Masquer la mention « Propulsé par » d’une extension de formulaire */
.exemple-formulaire .exemple-credit {
display: none;
}
Limite à connaître : le CSS masque, il ne supprime rien. Le HTML, les scripts et les styles de l’extension restent chargés. Pour retirer réellement un élément, il faut passer aux hooks.
2. Utiliser les hooks : actions et filtres prévus par l’extension
Les hooks sont des points d’accroche que l’auteur place dans son code. Une action exécute votre fonction à un moment précis (add_action()) ; un filtre reçoit une valeur, vous laisse la modifier et doit la renvoyer (add_filter()). L’extension appelle do_action() ou apply_filters(), vous vous y branchez depuis votre propre fichier : ses fichiers restent intacts et vos modifications survivent aux mises à jour. La documentation officielle des hooks détaille le mécanisme.
Trouver les hooks d’une extension
- La documentation de l’éditeur : les extensions sérieuses publient la liste de leurs actions et filtres.
- Le code source : une recherche dans le dossier de l’extension les liste tous, avec le fichier et la ligne (la commande trouve aussi les variantes
do_action_ref_array()etapply_filters_ref_array()).
grep -rnE "do_action|apply_filters" wp-content/plugins/nom-de-l-extension/
- Les gabarits : ouvrez le fichier qui produit l’affichage à modifier, les hooks y apparaissent à l’endroit exact où ils se déclenchent.
- Query Monitor, en local ou en préproduction : son panneau des hooks montre ceux qui se déclenchent sur la page affichée et les fonctions qui y sont branchées.
Modifier une valeur avec add_filter : priorité et nombre d’arguments
La signature complète est add_filter( $hook, $fonction, $priorite = 10, $nb_arguments = 1 ) (voir add_filter() sur developer.wordpress.org). Deux paramètres posent régulièrement problème :
- La priorité : les fonctions branchées sur un même hook s’exécutent de la plus petite priorité à la plus grande. Pour passer après l’extension ou le thème, qui utilisent souvent la valeur par défaut de 10, choisissez 20.
- Le nombre d’arguments : si le filtre transmet deux valeurs (un texte et le produit concerné, par exemple) et que vous avez besoin de la seconde, déclarez-le dans le quatrième paramètre. Sinon votre fonction ne reçoit que la première.
Et une règle absolue : un filtre renvoie toujours une valeur. Oublier le return vide le texte ou le réglage concerné partout où le filtre s’applique.
Retirer un comportement avec remove_action ou remove_filter
Pour supprimer ce que fait l’extension, appelez remove_action() ou remove_filter() avec le même hook, la même fonction et la même priorité que l’ajout d’origine. Au moindre écart, rien n’est retiré et aucune erreur ne s’affiche.
Le moment compte aussi : on ne peut retirer qu’une fonction déjà accrochée. Votre fichier peut être chargé avant l’extension (c’est toujours le cas d’un mu-plugin), d’où l’habitude de placer le retrait dans une fonction branchée sur init, ou plus tard si l’extension n’enregistre ses hooks qu’à ce moment-là. Enfin, quand le hook pointe vers la méthode d’un objet, il faut disposer de l’instance exacte de cet objet. Si l’extension ne l’expose pas, cherchez un filtre qui produit le même effet ou passez à une autre méthode.
3. Ranger votre code dans une extension compagnon ou un mu-plugin
Vos hooks ont besoin d’un fichier qui ne sera jamais écrasé. La solution la plus propre est une extension compagnon : un dossier wp-content/plugins/monsite-ajustements/ contenant un fichier monsite-ajustements.php. Elle s’active et se désactive comme n’importe quelle extension, ne dépend pas du thème et se versionne facilement. Voici un exemple complet avec WooCommerce :
<?php
/**
* Plugin Name: Mon site – Ajustements WooCommerce
* Description: Personnalisations de WooCommerce, rangées hors de l’extension pour survivre à ses mises à jour.
* Version: 1.0.0
* Requires at least: 6.5
* Requires PHP: 8.2
* Requires Plugins: woocommerce
* Author: Votre nom
* License: GPL-2.0-or-later
* Text Domain: monsite-ajustements
* Update URI: false
*/
defined( 'ABSPATH' ) || exit;
/**
* Filtre : texte du bouton des produits variables dans les listes de produits.
* Priorité 20 (après les filtres à la priorité par défaut), 2 arguments reçus.
*/
add_filter( 'woocommerce_product_add_to_cart_text', 'monsite_texte_bouton_variable', 20, 2 );
function monsite_texte_bouton_variable( $texte, $produit ) {
if ( $produit instanceof WC_Product && $produit->is_type( 'variable' ) ) {
return __( 'Choisir une option', 'monsite-ajustements' );
}
return $texte; // Un filtre renvoie toujours une valeur.
}
/**
* Action : ajoute une mention sous le bouton « Ajouter au panier » de la fiche produit.
*/
add_action( 'woocommerce_after_add_to_cart_button', 'monsite_mention_contact' );
function monsite_mention_contact() {
printf(
'<p class="monsite-mention">%s</p>',
esc_html__( 'Une question sur ce produit ? Écrivez-nous.', 'monsite-ajustements' )
);
}
/**
* Retrait : bloc UGS, catégories et étiquettes de la fiche produit.
* Même hook, même fonction, même priorité (40) que dans WooCommerce,
* et sur init, une fois WooCommerce chargé.
*/
add_action( 'init', 'monsite_retirer_meta_produit' );
function monsite_retirer_meta_produit() {
remove_action( 'woocommerce_single_product_summary', 'woocommerce_template_single_meta', 40 );
}
Ce que fait chaque partie :
- L’en-tête déclare l’extension (voir les en-têtes reconnus par WordPress).
Requires Plugins, apparu avec WordPress 6.5, liste les slugs du répertoire officiel dont elle dépend : elle ne peut pas être activée sans WooCommerce, et WooCommerce ne peut plus être désactivé tant qu’elle est active. Update URI: false, introduit avec WordPress 5.8, empêche WordPress de proposer comme « mise à jour » une extension homonyme du répertoire, qui écraserait la vôtre.Requires PHP: 8.2correspond à la plus ancienne branche de PHP encore maintenue (correctifs de sécurité jusqu’au 31 décembre 2026) ; WordPress recommande PHP 8.3 ou plus.defined( 'ABSPATH' ) || exit;empêche l’exécution du fichier hors de WordPress, et le préfixemonsite_évite les collisions avec les fonctions d’autres extensions.- Les textes passent par
__()etesc_html__()avec le text domain de l’extension : ils sont traduisibles, et la mention affichée par la fonction est échappée (WooCommerce échappe lui-même le texte du bouton).
Ces hooks agissent sur les gabarits PHP classiques de WooCommerce. Avec un thème de blocs, la fiche produit est assemblée à partir de blocs et certains de ces hooks ne sont pas déclenchés : vérifiez le résultat sur votre propre site. Si votre fichier grossit, découpez-le en classes et en responsabilités claires ; les principes SOLID appliqués à WordPress donnent une méthode.
Le mu-plugin (extension « indispensable ») est l’autre option. Un fichier PHP déposé directement dans wp-content/mu-plugins/ est chargé automatiquement, avant les extensions classiques et par ordre alphabétique, et ne peut pas être désactivé depuis l’administration. WordPress ne lit pas les sous-dossiers de ce répertoire, n’exécute pas de hook d’activation et ne signale aucune mise à jour (documentation des mu-plugins). Réservez-le au code qui ne doit jamais être coupé par erreur.
Le fichier functions.php du thème enfant convient seulement au code lié au thème : changez de thème, et ce code disparaît. Si vous partez de zéro, voici comment créer un thème enfant WordPress. Quant aux extensions d’extraits de code comme Code Snippets, elles dépannent ceux qui ne veulent pas créer de fichier, mais le code est alors stocké en base de données, hors de tout suivi de versions.
4. Surcharger un gabarit (template) de l’extension : l’exemple de WooCommerce
Certaines extensions cherchent d’abord leurs gabarits dans le thème actif avant d’utiliser les leurs. WooCommerce est l’exemple le plus connu : pour changer le HTML d’une page de la boutique, copiez un seul fichier du dossier wp-content/plugins/woocommerce/templates/ vers un dossier woocommerce/ de votre thème enfant, en gardant le même chemin, sans templates/. Exemple :
- original :
wp-content/plugins/woocommerce/templates/single-product/add-to-cart/simple.php; - copie à modifier :
wp-content/themes/votre-theme-enfant/woocommerce/single-product/add-to-cart/simple.php.
Copiez dans le thème enfant, jamais dans le thème parent, que ses propres mises à jour écraseraient. La contrepartie de cette méthode : votre copie est figée. Quand WooCommerce fait évoluer un gabarit, il change la ligne @version de son en-tête, et la page WooCommerce > État signale les copies devenues obsolètes : il faut alors reporter les changements dans la vôtre. C’est pourquoi la documentation de WooCommerce recommande d’utiliser d’abord les hooks présents dans chaque gabarit, et de ne copier un fichier que si aucun hook ne suffit.
Autre limite : cette documentation concerne les thèmes classiques. Les blocs de panier et de validation de commande n’utilisent pas ces gabarits PHP, et avec un thème de blocs une bonne partie de l’affichage passe par des modèles de blocs : une surcharge PHP peut alors rester sans effet. Pour un cas concret, voyez comment personnaliser la page de connexion de WooCommerce. D’autres extensions proposent le même mécanisme : vérifiez-le dans leur documentation.
5. Désactiver un script, un style ou un shortcode de l’extension
Beaucoup d’extensions chargent leurs fichiers sur toutes les pages, même là où elles ne servent pas. Vous pouvez les retirer avec wp_dequeue_script() et wp_dequeue_style(), sur le hook wp_enqueue_scripts avec une priorité élevée pour passer après l’extension. Exemple avec Contact Form 7, quand le formulaire ne figure que sur la page de contact :
add_action( 'wp_enqueue_scripts', 'monsite_alleger_contact_form_7', 100 );
function monsite_alleger_contact_form_7() {
if ( is_page( 'contact' ) ) {
return; // Le formulaire est sur cette page : on garde tout.
}
wp_dequeue_script( 'contact-form-7' );
wp_dequeue_style( 'contact-form-7' );
}
Le nom à utiliser, le « handle », se lit dans le code source de la page : une balise <script id="contact-form-7-js"> correspond au handle contact-form-7 (sans le suffixe -js, ou -css pour une feuille de style). Query Monitor les liste aussi. Vérifiez d’abord si l’extension prévoit un réglage ou un filtre pour cela : Contact Form 7 propose par exemple les filtres wpcf7_load_js et wpcf7_load_css. Pour comprendre la mécanique, lisez mon article sur le chargement des scripts et des styles dans WordPress.
Pour changer l’affichage d’un shortcode de l’extension, retirez-le avec remove_shortcode() puis enregistrez le même nom avec votre propre fonction, une fois l’extension chargée. Ici, le shortcode [exemple_galerie] est un nom fictif à remplacer par le vrai :
add_action( 'init', 'monsite_remplacer_shortcode', 20 );
function monsite_remplacer_shortcode() {
remove_shortcode( 'exemple_galerie' );
add_shortcode( 'exemple_galerie', 'monsite_shortcode_galerie' );
}
function monsite_shortcode_galerie( $atts ) {
$atts = shortcode_atts(
array(
'titre' => '',
),
$atts,
'exemple_galerie'
);
// Votre propre rendu, toujours échappé.
return '<div class="monsite-galerie"><p>' . esc_html( $atts['titre'] ) . '</p></div>';
}
6. Le fork : copier et renommer l’extension, en dernier recours
Quand le besoin touche une partie du code qu’aucun hook n’expose, ou quand l’extension est abandonnée par son auteur, il reste le fork : une copie que vous faites vôtre. Pour qu’elle ne soit jamais écrasée, renommez le dossier, le nom de l’extension, son text domain et les préfixes de ses fonctions et de ses classes (sinon l’original et la copie entrent en conflit s’ils sont actifs en même temps), puis ajoutez Update URI: false à l’en-tête :
<?php
/**
* Plugin Name: Nom d’origine (version modifiée pour mon site)
* Text Domain: nom-origine-monsite
* Update URI: false
*/
Mesurez bien les conséquences : vous ne recevrez plus aucun correctif de l’auteur, y compris de sécurité. C’est à vous de surveiller les failles publiées pour l’original et de reporter les correctifs. Vérifiez aussi la licence : les extensions du répertoire officiel sont sous licence GPL ou compatible, ce qui autorise la modification ; pour une extension commerciale, lisez ses conditions. Avant d’en arriver là, demandez à l’auteur d’ajouter le filtre qui vous manque, sur son forum de support ou son dépôt de code : c’est souvent la solution la plus durable.
Tester vos modifications en local, puis en préproduction
Modifier un plugin WordPress se fait en local, jamais directement sur le site en ligne. Copiez le site (fichiers et base de données) dans un environnement local : wp-env, l’outil officiel basé sur Docker, WordPress Playground pour un essai rapide dans le navigateur, ou l’outil local de votre choix. Activez le journal des erreurs dans wp-config.php pour voir les avertissements sans les afficher aux visiteurs :
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
Le journal est écrit dans wp-content/debug.log, un fichier que le serveur web sert par défaut à qui connaît son adresse : ne laissez pas ces réglages actifs sur un site en ligne. Versionnez votre extension compagnon avec Git : vous saurez toujours ce qui a changé et quand. Ensuite, à chaque nouvelle version de l’extension modifiée :
- Sauvegardez le site, fichiers et base de données.
- Lisez le journal des modifications de l’extension : un hook renommé ou supprimé, un gabarit en nouvelle version y apparaissent.
- Mettez à jour en préproduction, une copie du site en ligne, et testez les pages concernées par vos modifications.
- Déployez en production une fois les tests validés.
Sur les sites dont j’assure la maintenance, chaque mise à jour passe d’abord par une préproduction : c’est là qu’un hook disparu se repère, avant vos visiteurs. Si vous préférez déléguer ce suivi, voyez comment se déroule la maintenance d’un site WordPress avec tests en préproduction.
Quand vaut-il mieux une extension dédiée ?
Les hooks ont leurs limites. Quelques signaux montrent qu’il est temps de changer d’approche :
- vos ajustements s’empilent et chaque mise à jour de l’extension devient un chantier ;
- le fork est devenu permanent et vous n’avez plus le temps d’y reporter les correctifs ;
- l’extension fait dix fois plus que nécessaire et pèse sur les performances ;
- le besoin repose sur une logique métier ou une connexion à un autre logiciel qu’aucune extension ne prévoit.

Il existe souvent une voie intermédiaire : partir d’une extension éprouvée et la compléter. C’est l’approche retenue pour un cabinet de neuropsychologie, dont l’agenda en ligne repose sur l’extension de réservation BookingPress, personnalisée et complétée par des fonctionnalités codées sur mesure. Le détail est dans l’étude de cas de ce cabinet de neuropsychologie, et le principe est décrit sur la page consacrée à la prise de rendez-vous en ligne intégrée à un site WordPress.
Quand aucune extension ne convient, mieux vaut écrire la sienne que de tordre celle d’un autre : vous pouvez apprendre à créer votre propre plugin WordPress, ou faire développer une extension adaptée à votre besoin.
Questions fréquentes sur la modification d’un plugin WordPress
Vous hésitez entre un hook, une surcharge de gabarit et un fork, ou votre besoin dépasse ce qu’une extension existante permet ? Décrivez-moi votre besoin : je vous dirai quelle approche convient à votre site.
Mis à jour en octobre 2026 par un développeur WordPress freelance senior.