Tout savoir sur WordPress

Les bonnes pratiques de développement d’une extension WordPress

Le code de votre plugin doit être maintenable et compréhensible pour tout le monde. À travers ce guide complet, vous allez découvrir toutes les bonnes pratiques de développement d’une extension WordPress.

Cet article fait suite à la conférence tenue lors du WP Tech 2015 à Nantes. Les slides de la conférence sont disponibles ici : http://slides.com/jonathanbuttigieg/bonnes-pratiques-plugin-wordpress

Quelque soit la raison du développement d’un plugin WordPress, on se doit de respecter quelques bonnes pratiques de développement. Afin que son code soit lisible et que le développement d’une extension soit facile à prendre en main par une tierce personne, il suffit de suivre quelques règles simples à mettre en place.

L’idée de la conférence est venue suite à une mésaventure avec le plugin Revolution Slider. Le plugin fait bien son travail, c’est-à-dire créer des sliders sur son site Internet. Le problème est qu’il est impossible de pouvoir se greffer dessus pour modifier son comportement. Le code n’est pas lisible/compréhensible et il ne contient aucun hooks.

1- Créer un fichier contributors.txt

Le fichier contributors.txt permet de récupérer les informations de contact des intervenants du plugin. Il n’y a pas de norme à suivre au niveau des contacts à renseigner. On peut donc ajouter un email, un compte twitter ou même un numéro de téléphone.

C’est un moyen simple et efficace pour être joignable à tout moment par d’autres personnes qui souhaiteraient vous interroger sur l’extension.

Par exemple, vous êtes un développeur en agence, le développement d’un plugin a été effectué par une personne qui ne fait plus partie de l’équipe. Vous seriez content d’être en mesure de contacter cette personne pour lui poser des questions pour mieux comprendre son code et pouvoir reprendre le développement dans de bonnes conditions.

Voici le contenu du fichier contributors.txt d’Imagify :

Fichier contributors.txt d'Imagify

Ce fichier doit être placé à la racine du projet.

À savoir qu’il existe aussi un fichier du même genre pour indiquer les informations de contact des développeurs d’un site Internet. Il s’agit du fichier humans.txt.

2. Commenter son code

Il est impossible de concevoir un plugin sans aucun commentaire dans son code. Que ce soit pour vous plus tard ou pour d’autres personnes, c’est un point d’honneur que vous devez accorder à vos développements.

Il n’y a rien de plus frustrant qu’un code non-commenté lorsqu’on souhaite comprendre la logique et le fonctionnement d’un code !

3170366

On fait quoi avec ça ?

Ci-dessous, une fonction du plugin Revolution Slider :

Une fonction non-commentée du plugin Revolution Slider

À moins d’être le développeur du plugin, il est difficile de comprendre l’utilité de cette fonction et savoir comment s’en servir.

Pour commencer, il n’y a aucune information sur les paramètres de la fonction. On peut aisément deviner le type de $title et $alias. Par contre, quel est le type de $params ? À quoi sert ce paramètre qui n’est pas ré-utilisé dans la fonction ? Pourquoi existe-t-il ?

Enfin, à quoi sert la vérification de la méthode isAliasExistsinDB() ? On peut le deviner au nom de la méthode, mais allons-nous devoir jouer à ce jeu tout le temps ?

Voilà qui est mieux !

Voici l’exemple d’une fonction avec des commentaires :

Une fonction commentée du plugin Imagify

C’est tout de suite plus facile à comprendre !

Le commentaire d’une fonction doit contenir les éléments suivants :

  • une description qui indique l’objectif de la fonction
  • depuis quelle version la fonction est déclarée dans le plugin
  • la liste de tous les arguments en indiquant leur type et une description
  • le retour de la fonction en mentionnant leur type et une description

Si vous vous êtes inspiré d’une autre fonction ou d’un code disponible en ligne, vous pouvez le préciser en ajoutant une ligne débutant par @source avec un lien vers la source comme ci-dessous :

Une fonction du plugin Imagify qui indique sa source

Un commentaire est présent au dessus de la fonction is_imagify_blocked() pour expliquer le principe de la vérification que l’on souhaite effectuer. Une  ligne de code supplémentaire permet à tous de comprendre ce qui est en train d’être fait à ce moment là.

L’ajout des commentaires dans un plugin est très simple à faire. Pourtant, la plupart des plugins disponibles sur le répertoire de WordPress ou des plugins premiums n’en contiennent pas. Afin d’aider les autres à mieux comprendre votre code, prenez le réflexe d’en mettre dès que possible.

Un bon exemple à suivre est WordPress lui-même. Si vous avez 5 minutes, ouvrez l’un des fichiers du core ;)

3. Définir une architecture

La mise en place d’une architecture de dossiers est un moyen simple pour trier ses fichiers par “catégorie” et de les retrouver plus facilement par la suite. Il n’existe pas d’architecture parfaite. Par contre, en avoir une est indispensable pour la maintenabilité de votre plugin.

Voici un exemple expliqué en vidéo :

Pour résumer la vidéo, voici une idée d’architecture à adopter ou à adapter en fonction de votre besoin :

  • assets : fichiers CSS, JS et images
  • inc : fichiers PHP
  • inc/3rd-party : hooks pour compatibilité avec autres plugins / themes
  • inc/admin : hooks déclenchés dans l’admin
  • inc/api : fichiers des APIs externes
  • inc/classes : fichiers de classes
  • inc/common : les hooks déclenchés sur le front et l’admin
  • inc/front : hooks déclenchés dans le front
  • inc/functions : déclarations des fonctions
  • languages : fichiers de traductions

En image avec l’architecture du plugin Imagify :

Architecture des dossiers du plugin Imagify

Prenez le temps de revoir votre architecture et de la ré-adapter en fonction de votre besoin, cela vous fera gagner du temps par la suite !

 4. Préfixer les fonctions

Pour éviter des conflits avec d’autres plugins, il est recommandé de préfixer toutes les fonctions de votre plugin.

La meilleure solution pour résoudre ce problème est d’utiliser les espaces de noms de PHP. Cependant, vous devez être certain que tous les utilisateurs du plugin ont au minimum PHP 5.3 installé sur leur serveur.

Si vous êtes une agence qui développe un plugin pour le site d’un client, alors vous pouvez devez utiliser les espaces de noms. Par contre, si vous développez un plugin qui est disponible gratuitement sur le répertoire de WordPress ou que vous le commercialisez, alors vous devriez plutôt suivre les  prochaines recommandations.

Les fonctions du plugin

Vous devez préfixer toutes les fonctions de votre plugin. On dit bien “toutes” sans aucune exception. Quelque soit le nom de votre fonction, c’est une obligation de la préfixer pour ne pas avoir de conflit et provoquer une erreur PHP fatale.

La bonne pratique est de préfixer ses fonctions par le nom de son plugin ou son abréviation, par exemple :

Une fonction du plugin Imagify préfixée

Les fonctions dites Private Scope

La plupart du temps, lorsqu’on déclare une fonction de retour utilisée par un hook (action ou filtre), cette fonction est appelée qu’une seule fois. C’est pour cette raison qu’il est intéressant d’indiquer aux autres développeurs que cette fonction ne peut pas être ré-utilisée. C’est ce qu’on appelle une fonction dite Private Scope, c’est-à-dire que cette fonction répond à un besoin unique.

La norme est de préfixer ses fonctions par un underscore comme ci-dessous :

Une fonction dite Private Scope du plugin Imagify

Les librairies externes

On peut être amené à utiliser des librairies externes dans nos plugins. La norme est de ne pas modifier les noms des fonctions et des classes d’une librairie. Pour déterminer si on doit l’inclure ou non, la bonne pratique est de vérifier si l’une des constantes, fonctions ou classes de la libraire existe. Ainsi, on évite les potentiels conflits avec d’autres extensions susceptibles d’utiliser la même librairie.

En théorie cela devrait suffire, mais en pratique ce n’est pas suffisant !

Nous avons eu la mauvaise expérience avec WP Rocket qui utilise la libraire ip_in_range.php. Elle est aussi utilisée par l’extension officielle de CloudFlare. Dans WP Rocket, nous avons modifié ce fichier pour vérifier si les fonctions existent avant de les déclarer comme ci-dessous :

Vérification de la déclaration d'une fonction dans WP Rocket

Malgré cette vérification, des conflits de déclaration existent encore. Par exemple, si vous avez WP Rocket sur votre site et que vous décidez d’installer le plugin CloudFlare, une erreur fatale sera déclenchée.

Pourquoi l’erreur est présente alors que WP Rocket vérifie si la fonction existe ?

Il y a deux raisons :

  • CloudFlare déclare les fonctions sans vérifier qu’elles sont déjà déclarées par un autre script.
  • CloudFlare est chargé après WP Rocket. C’est-à-dire que lorsque cette extension est activée, WP Rocket a déjà vérifié si les fonctions de la librairie existaient ou non. Puisqu’aucun autre script l’a fait avant lui, il les déclare, ce qui provoquera une erreur fatale après l’activation de CloudFlare qui ne fait pas la vérification.

Voici un exemple en vidéo :

Pour résoudre le problème, il est donc conseillé de préfixer toutes les fonctions/classes de la librairie. C’est ce que nous avons fait depuis la version 2.6.13 de WP Rocket pour éviter les conflits avec l’extension de ClouFlare.

Par exemple, decbin32() a été renommée rocket_decbin32() :

Une fonction d'une librairie externe préfixée dans WP Rocket

5. Définir une constante de version

C’est l’une des parties les plus importantes de cet article. Grâce à la définition d’une constante et d’une option qui stockent la version de votre plugin, vous allez pouvoir gérer de façon efficace la première installation et les nouvelles mises à jour de votre extension.

Par exemple, lorsque le plugin est activé pour la première fois, on doit pouvoir initialisé les valeurs de nos options afin d’avoir notre réglage par défaut.

Concernant les mises à jour d’un plugin WordPress, il est possible de le faire à partir de deux méthodes :

  • via son administration WordPress en cliquant sur le lien de mise à jour
  • via son FTP en remplaçant manuellement les fichiers de l’extension

Dans les deux cas, nous devons avoir la possibilité d’exécuter un script, en cas de besoin, après une mise à jour.

Pour que ce soit plus clair, je vous explique en détail le processus dans cette vidéo :

6. Gérer les états du plugin

Le terme “état” représente 3 actions du plugin : activation, désactivation et suppression. Vous pouvez avoir des choses à faire lors de ces différentes actions avec votre plugin.

Par exemple, avec WP Rocket, lors de l’activation ou de la désactivation du plugin, nous devons modifier le contenu du fichier .htaccess et wp-config.php.

6.1 Activation

Pour intervenir lors de l’activation d’une extension, il faut utiliser la fonction register_activation_hook().

Voici un exemple d’utilisation provenant du Codex de WordPress :
[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

register_activation_hook( __FILE__, 'myplugin_activate' );
function myplugin_activate() {
    // Code de vos différentes actions lors de l'activation ici
}

[/pastacode]
La fonction prend les paramètres $file et $action :

  • $file: chemin vers le fichier principal du fichier. Pour récupérer ce chemin, vous pouvez utiliser __FILE__.
  • $function: la fonction qui sera déclenchée lors de l’activation du plugin

6.2 Désactivation

Lors de la désactivation d’un plugin, il faut vous servir de register_deactivation_hook(). Les paramètres de la fonction et son utilisation sont les mêmes que register_activation_hook().
[pastacode lang=”php” message=”” highlight=”” provider=”manual”]

register_deactivation_hook( __FILE__, 'myplugin_deactivate' );
function myplugin_deactivate() {
     // Code de vos différentes actions lors de la désactivation ici
}

[/pastacode]
Attention, vous ne devez pas supprimer les options de l’extension à ce moment là. Par exemple, le plugin WP Fastest Cache supprime ses options lorsque vous le désactivez. Pourquoi ?!

Vous pouvez désactiver un plugin temporairement pour diverses raisons. Par contre, vous ne souhaitez pas perdre les réglages que vous avez mis en place. Cet action doit être réalisée uniquement lors de la suppression du plugin. C’est à ce moment là que l’utilisateur ne souhaite plus utiliser votre extension.

6.3 Suppression

Lorsqu’un utilisateur décide de supprimer un plugin, c’est qu’il n’a plus besoin de l’utiliser. Il faut donc que vous supprimiez toutes les options et autres informations stockées par l’extension.

Pour cela, vous devez utiliser le fichier uninstall.php que vous devez placer à la racine du plugin.

Voici un exemple d’utilisation avec le fichier unistall.php d’Imagify :

Le fichier uninstall.php du plugin Imagify

7. Ajouter des hooks

Les hooks de WordPress permettent d’intervenir à un moment clé du processus de WordPress ou de modifier le retour de ses fonctions. Grâce à ces hooks, il est possible d’étendre les capacités de WordPress à l’infini. C’est en partie grâce aux hooks que WordPress est aujourd’hui le CMS le plus populaire et le plus utilisé du marché.

Lors du WP Tech 2015, Julio Potier a tenu une conférence très intéressante sur l’utilisation des hooks.

Voici les slides de sa conférence qui est un excellent complément à cette partie : Comment créer des hooks dans vos développements WordPress.

Lors du développement de vos plugins, vous devez adopter la même philosophie que WordPress. C’est-à-dire que vous devez ajouter des actions et des filtres autant que vous le pouvez. Il vaut mieux avoir trop de hooks que ne pas en avoir assez.

L’objectif des hooks est de permettre à n’importe qui d’étendre les fonctionnalités de votre plugin et de les adapter à son besoin. Pour cela, vous devez adopter deux réflexes :

– Ajouter un hook d’action avant et après une action particulière dans votre extension. Par exemple, dans WP Rocket, vous avez un hook d’action avant et après la purge des fichiers minifiés mis en cache.

Exemple d'actions dans le plugin WP Rocket

– Ajouter un hook pour filtrer le retour d’une fonction dès qu’elle retourne quelque chose. Par exemple, dans WP Rocket, vous pouvez modifier le contenu de toutes les règles qui sont ajoutées dans le fichier .htaccess :

Un filtre du plugin WP Rocket

En suivant cela, vous allez faciliter le développement et la maintenance de votre extension. Que ce soit pour vous-même afin d’assurer la compatibilité du plugin avec autre ou à l’inverse pour que d’autres plugins puissent se greffer au vôtre.

Voici une vidéo avec quelques exemples d’utilisation et de cas pratiques :

Conclusion

Bien que pas mal de chose aient été abordées dans cet article, il reste encore quelques points importants comme le versionning du code avec Git ou la mise en place d’un code review. Ces deux sujets feront certainement l’objet d’un nouvel article.

Pour résumer ce qui a été abordé, vous devez penser dès le début de votre extension que votre code doit être facilement maintenable et compréhensible pour tous. À l’aide de ces méthodes simples, vous avez toutes les cartes en main pour développer un plugin comme un pro :)

Merci d’avoir lu cet article ! N’hésitez pas à partager en commentaire vos bonnes pratiques de développement d’un plugin WordPress.

Cet article a été mis à jour il y a 3024 jours - Il n'est peut être plus à jour !

Article écrit par Jonathan B.

Jonathan est le co-fondateur de WP Media, startup connue pour être l’auteur de WP Rocket et Imagify. Il est aussi co-organisateur du WordCamp Lyon et Paris.

16 Commentaires

    • Merci pour ton retour. N’hésites pas si tu as des questions – j’y répondrai avec grand plaisir !

  1. Bravo pour cette article très précis, qui montre l’intérêt des hooks dans du dev wordpress maison ou pro… On les utilise pas assez, malheureusement… et regrette d’avoir loupé la conférence WP Tech 2015 à Nantes, peut être la prochaine fois ;)
    @+

    • Salut ! Les hooks, c’est la vie :)

      La vidéo de la conférence du WP Tech sera disponible prochainement.

      @ bientôt

  2. Au delà de la qualité de la conférence et de cet article condensé, j’apprécie tout particulièrement ton antipathie vis-à-vis du plugin Revolution Slider et je comprends pourquoi. :D

  3. Bonjour,

    Merci pour cet article fort utile et très précis qui me eprmet d’en apprendre encore d’avantage sur wordpress.

    J’essaie de remplacer petit à petit, tous les plugins qui concernent des fonctionnalités “front” (en majorité pour afficher des informations). J’aimerai parvenir à ne plus utiliser comme plugin du répertoire wordpress que ceux qui concernent le back office (sauvegarde & sécurité)

    Etant très attentif au sujet de la sécurité, avez-vous des références concernant les bonnes pratiques de développement des plugins concernant cet aspect ?

    Merci !

  4. Bonsoir,
    je viens de découvrir votre site, c’est une découverte magnifique ! Les tutos, les astuces .. Tout est claire et compréhensible . Dommage que vous n’avez pas publié de nouveautés depuis un long moment et que la plupart des astuces et tutoriels date de 2012 . La technologie est en cours de développement et 4 ans est trop long ! Je ne sais pas si c’est encore utile ou pas avec les gigantesques changements et mises à jour de WordPress.
    Cordialement.

    • @Yosra: Merci pour votre retour. La plupart des astuces sur ce blog sont toujours fonctionnelles malgré l’âge :)

  5. Bonjour,
    Super article très utile et très clair!
    Par contre aucune des vidéos annoncées ne s’affichent sur mon navigateur (j’en ai utilisé plusieurs) Est-qu’il me manque un plugin ou quelque chose ?

  6. bonjour, je viens de lire votre article très intéressant mais impossible de faire une appli sans faire apel à un devellopeur douée je pense, c’est toujours ca d’appris. merci pour le contenu interessant. bonne continuation.

  7. Bonjour,

    développent des petits plugin depuis quelques année en “autodidacte”, cette article est vraiment très instructif.

    Il me reste un problème maintenant, comment faire en sorte que lors de mes évolutions de plugin, cela informe les différents sites où il sont par un “mettre à jour” dans la liste des extensions?
    Je n’ai pas trouvé où stoker mes plugins et comment faire la “liaison”?

    • Il faut mettre ton plugin sur le répertoire des extensions WP !
      https://wordpress.org/plugins/

      Cependant s’il est full premium (je te conseille tout de même une version gratuite) tu peux utiliser EDD et Software licensing pour gérer les licences et les mises à jour depuis ton site