Créer un plugin Wordpress

13 December 2011 par Franck de Védrines

WordPress est aujourd’hui un CMS (Content Management System ou "système de gestion de contenu" en Français) incontournable et il serait dommage de ne pas profiter des fonctionnalités qu’il nous offre.

Nous verrons dans cet article comment développer un module WordPress de A à Z.
Au fil de ce tutoriel, nous allons créer un petit plugin ("wp_customtext") permettant d’ajouter X fois un texte à la fin de chaque billet.
Ce plugin est inutile en soi, mais permet de bien comprendre et manipuler les concepts essentiels à la création d'un plugin, comme la gestion des filtres, la gestion des actions, l’interaction avec la base de données, l'espace d'administration etc.
Libre à vous de développer vos propres plugins par la suite.

Pré-requis

Pour installer un plugin WordPress, il y a un seul pré-requis qui paraît évident, c'est d'avoir préalablement installé WordPress sur son site.
L’installation se fait très simplement, et en quelques secondes seulement.
Vous pouvez télécharger WordPress sur la page de téléchargement officielle de WordPress.

Structure

Tout d’abord, il faut savoir que les plugins WordPress sont stockés dans le répertoire "/wp-content/plugins/".
Il faut ensuite ensuite créer le dossier du plugin dans ce répertoire.
Ainsi, la structure du plugin ressemblera à ça :

  • wp-content/plugin/wp_customtext/ : racine
  • wp-content/plugin/wp_customtext/readme.txt : obligatoire si le plugin est publié
  • wp-content/plugin/wp_customtext/wp_customtext.php : fichier principal
  • wp-content/plugin/wp_customtext/css : feuilles de style
  • wp-content/plugin/wp_customtext/php : les fichiers PHP
  • wp-content/plugin/wp_customtext/js : les fichiers Javascript
  • wp-content/plugin/wp_customtext/lang : les fichiers de traduction

Fichier principal

Afin d’indiquer à WordPress qu’il s’agit d’un plugin, le fichier principal (wp_customtext.php) doit contenir les en-têtes suivantes :

/*
Plugin Name: Nom du plugin
Plugin URI: URL de l’article de description
Description: Brève description
Version: Version du plugin (par exemple : 0.5)
Author: L’auteur du plugin
Author URI: L’URL de l’article présentant l’auteur
*/

La classe

On va ensuite créer la classe principale de notre plugin et en déclarer une nouvelle instance :

class customtext {
   function  __construct() {
      // Rien pour l’instant
   }
}
 
if (class_exists('customtext')) {
   $customtext = new customtext();
}

Les actions

Dans WordPress, les actions jouent un rôle très important puisque ce sont des fonctions qui seront appelées lors d’évènements particuliers.
C’est par exemple grâce à ces fonctions que l’on va envoyer un mail dès qu’un article est posté.

Ajouter une action

La fonction a appeler est la fonction "add_action" et sa définition est la suivante :

add_action($tag, $function_to_add, [$priority], [$accepted_args]);

Expliquons les paramètres de cette fonction:

  • (string) $tag correspond au nom de l’action sur laquelle on veut se brancher.
    Vous pouvez voir la liste des actions disponibles sur la documentation officielle des actions WordPress
  • (callback) $function_to_add correspond à la fonction à appeler
  • (int) (facultatif) $priority correspond, comme son nom l’indique, à l’importance de la fonction (10 par défaut). Plus sa valeur est faible, plus elle sera appelée tôt.
  • (int) (facultatif) $accepted_args correspond au nombre d’argument(s) de la fonction $function_to_add.

Dans notre plugin, on va ajouter les fichiers css et js en appelant la fonction "add_action".
Dans notre cas, le paramètre $function_to_add est un tableau car la fonction est celle d’une classe.
Il faut donc préciser l'instance :

// On appelle la fonction addHeader
add_action('wp_head', array($customtext, 'addHeader'));

Dans notre classe 'customtext', on ajoute donc la function "addHeader" :

function addHeader() {
   // Ajout du fichier css
   print '<link media="screen" type="text/css" href="/wp-content/plugins/wp_customtext/css/style.css" rel="stylesheet">';
   // Ajout du fichier javascript
   print '<script type="text/javascript" src="/wp-content/plugins/wp_customtext/js/main.js"></script>';
}

Supprimer une action

Pour supprimer une action, il suffit d’appeler la fonction "remove_action" qui prend les mêmes paramètres que la fonction "add_action" :

remove_action($tag, $function_to_remove, [$priority], [$accepted_args]);

Les filtres

Les filtres sont également très importants dans WordPress car ils vont vous permettre de modifier le contenu du site.
C’est avec eux que l’on pourra, par exemple, ajouter un texte à la fin d’un billet, modifier le format des dates, modifier les avatars des commentaires, etc.
La liste des filtres est disponible sur la documentation officielle des filtres WordPress.

Ajouter un filtre

L’ajout de filtres est vraiment très simple d’utilisation et fonctionne à peu près de la même manière que la fonction d’ajout d’une action.
Pour ajouter un filtre, on utilise la fonction "add_filter" dont la définition est :

add_filter($tag, $function_to_add, [$priority], [$accepted_args]);

Nous allons maintenant essayer d’ajouter un texte à la fin de chaque billet. Pour cela, dans notre classe principale, nous allons créer notre fonction qui va modifier le contenu de l’article :

function modifyArticle($content = '') {
   $content .= 'texte ajouté à la fin du billet';
   return $content ;
}

Le filtre qui nous intéresse ici est "the_content".
Il est exécuté à chaque fois que l’on affiche un billet. On va donc l’accrocher à notre fonction "modifyArticle" :

add_filter('the_content', array($customtext, 'modifyArticle'));

Supprimer un filtre

Pour supprimer un filtre, on utilise la fonction "remove_filter" dont les paramètres sont identiques à la fonction add_filter :

remove_filter('the_content', array($customtext, 'modifyArticle'));

Modification du Header

Pour ajouter nos fichiers css et Javascript, nous avons utilisé les actions afin d’appeler une fonction qui, elle, se charge d’inclure les fichiers.
Mais cette solution n’est pas idéale pour plusieurs raisons :

  • Les fichiers ajoutés (jQuery par exemple) ont peut-être déjà été ajoutés à travers d’autres plugins : il y a donc duplication de code et cela peut entraîner de nombreux problèmes
  • Certaines bibliothèques sont déjà livrées avec WordPress (voir la liste des bibliothèques livrées avec WordPress)

Javascript

Pour charger une bibliothèque JavaScript livrée avec WordPress, il suffit d’appeler la fonction "wp_enqueue_script" avec le nom de la bibliothèque en paramètre.
Par exemple, pour inclure la bibliothèque jQuery, il suffit d’écrire :

wp_enqueue_script('jquery').

Pour charger vos propres fichiers, cela fonctionne de la même manière :

wp_enqueue_script('wp_customtextJS', '/wp-content/plugins/customtext/js/main.js');

CSS

Pour inclure vos feuilles de style, il suffit d’appeler la fonction "wp_enqueue_style" :

wp_enqueue_style('wp_customtextCSS', '/wp-content/plugins/customtext/css/style.css');

Administration

Le panneau d’administration est un élément essentiel de votre plugin. Il permettra à l’utilisateur de votre plugin de configurer les différentes options.
Pour stocker ces données, WordPress nous fournit le système d’options, bien pratique et simple d’utilisation.

Déclaration des options

Les options d’administration doivent être uniques et définies comme attributs de la classe principale ("customtext" dans notre cas) :

   class customtext {
      var $optionPlugin = 'wp_customtextOptions';
      function  __construct() {
      }
}

Options par défaut

Lorsque l’administrateur active le plugin pour la première fois, les différentes options ne sont pas initialisées.
Il va donc falloir définir les valeurs par défaut de nos options.
Il est conseillé de créer une fonction d’initialisation des options, cela afin d’éviter d’alourdir le constructeur et de pouvoir ajouter de nouvelles options facilement.
La fonction suivante permet d’initialiser les options et d’écraser les anciennes valeurs des options (si elles existaient) :

function initOptions() {
   $wp_customtextOptions = array(
      'displayText'       => '',
      'nbOccurences' => 0
   );
 
   $alreadyDeclaredOptions = get_option($this->optionPlugin);
   foreach ($alreadyDeclaredOptions as $key => $opt) {
      $wp_customtextOptions[$key] = $opt;
   }
   update_option($this->optionPlugin, $wp_customtextOptions);
 
   return $wp_customtextOptions;
}

La page d’administration

On va tout d’abord créer une fonction (toujours dans la classe principale) qui va se charger d’afficher notre page d’administration.

function displayPageAdmin() {
   $options = get_option($this->optionPlugin);
   if (isset($_POST['wp_customtextOptionUpdate'])) {
      if (isset($_POST['displayText'])) {
         $options['displayText'] = $_POST['displayText'];
      }
      if (isset($_POST['nbOccurences']) &#038;& is_numeric(intval($_POST['nbOccurences']))) {
         $options['nbOccurences'] = intval($_POST['nbOccurences']);
      }
      update_option($this->optionPlugin, $options);
   }
   // On affiche notre formulaire
   echo '<form method="post" action="' . $_SERVER["REQUEST_URI"] . '">
      <label for="displayText">Texte à ajouter à la fin des billets :</label>
      <p><input type="text" name="displayText" value="' . $options['displayText'] .'" /></p>
      <label for="nbOccurences">Nombre de fois :</label>
      <p><input type="text" name="nbOccurences" value="' . $options['nbOccurences'] . '" /></p>
      <input type="submit" name="wp_customtextOptionUpdate" value="Mettre à jour" />
   </form>';
}

Voici ce qu’il se passe :

  • On récupère la valeur des options
  • Si le formulaire a été soumis, on met à jour les options
  • On affiche le formulaire avec la valeur de l’option dans l’input

À ce niveau, la fonction est bien créée, mais n’est jamais appelée. On va d’abord créer un nouvel élément dans le menu de configuration (menu "Réglages").
Pour cela, on va faire appel à la fonction "add_options_page" dont la définition est :

add_options_page($page_title, $menu_title, $capability, $menu_slug, $function).

Pour plus d’informations sur cette fonction, consultez la documentation relative à la fonction add_options_page.
Cette fonction devra être en dehors de notre classe principale :

if (!function_exists('wp_customtext_update')) {
   function wp_customtext_update() {
      global $customtext;
      add_options_page('Administration', 'CustomText', 9, basename(__FILE__), array($customtext, 'printAdminPage'));
   }
}

Il suffit ensuite d’ajouter une action afin d’appeler notre fonction "wp_customtext_update" :

add_action('admin_menu', 'wp_customtext_update');

Nous pouvons maintenant modifier notre fonction "modifyArticle" afin qu’elle affiche, à la fin de chaque article, le texte définit dans l’espace d’administration X fois :

function modifyArticle($content = '') {
   $options = get_option($this->optionPlugin);
   $nbOccurence = $options['nbOccurences'];
   $textToDisplay = $options['textToDisplay'];
 
   for ($i = 0; $i < $nbOccurence; $i++) {
      $content .= $textToDisplay;
   }
 
   return $content;
}

Base de données

Pour stocker les données, il est possible d’utiliser les options.
Cependant, bien souvent, les plugins ont besoin de disposer de leur propre structure pour stocker ces données.
Il va donc falloir créer notre (ou nos) propre(s) table(s) dans la base de données lors de l'installation du plugin, mais également supprimer cette (ou ces) table(s) lors de la désinstallation du plugin

Installation de la base de données

Il va tout d’abord falloir créer une fonction qui va être appelée lors de l’installation de notre plugin. Pour cela, on va se servir de l’objet "$wpbd" qui permet d’accéder à la base de données :

/**
* @global $wpdb ;
**/
function installDB() {
   global $wpdb;
   $tableName = $wpdb->prefix . 'customtext_option';
 
   $sql = 'CREATE TABLE `' . $tableName . '` (';
   $sql .= '`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY, ';
   $sql .= '`number_occurence` INT NOT NULL DEFAULT 1';
   $sql .= ');';
 
   require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
   dbDelta($sql);
   add_option('customtext_db_version', '1.0') ;
}

Analysons ce code :

  • Le commentaire "@global $wpdb" permet d’avoir l’autocomplétion sur cette objet dans votre IDE
  • $wpdb->prefix permet de récupérer le préfixe de la base de données. Il a été défini lors de l’installation de WordPress (par défaut, il vaut 'wp_')
  • La fonction dbDelta permet d’examiner la structure de la table (ici "prefix_customtext_option") afin de l’ajouter ou de la mettre à jour si elle existe déjà
  • add_option('customtext_db_version', '1.0') permet d’ajouter une option définissant la version de la structure de nos tables afin de pouvoir faire évoluer le plugin facilement.

On appelle maintenant la fonction register_activation_hook qui va appeler la fonction de callback lors de l’installation du plugin :

register_activation_hook(__FILE__, array($customtext, 'installDB'));

Désinstallation de la base de données

Lors de la désactivation du plugin, il est bon de supprimer la (ou les) table(s) que l’on a créé afin de ne pas se retrouver avec des tables inutilisées.
On supprime également les options qui ont été définies pour ce plugin.
De la même façon, il faut écrire la fonction de suppression de la (ou les) table(s) :

/**
* @global wpdb $wpdb
*/
function uninstallDB() {
   global $wpdb;
   $tableName = $wpdb->prefix . 'customtext_option';
   $sql = 'DROP TABLE`' . $tableName . '`';
   $wpdb->query($sql);
 
   delete_option($this->optionPlugin);
   delete_option('customtext_db_version');
}

On appelle maintenant la fonction "register_deactivation_hook" qui va appeler la fonction de callback lors de la désinstallation du plugin :

register_deactivation_hook(__FILE__, array($customtext, 'uninstallDB'));

Utilisation des données

Pour utiliser les données stockées en base, c’est très simple :

  • On utilise la méthode "prepare" pour protéger notre requêtre
  • On récupère les résultats avec la méthode "get_results"

Exemple :

/**
* @global wpdb $wpdb
*/
function retrieveNbOccurence() {
   global $wpdb;
 
   $tableName = $wpdb->prefix . 'customtext_option';
   $sql = $wpdb->prepare('SELECT number_occurence FROM ' . $tableName);
   $result = $wpdb->get_results($sql)
   $nbOccurence = $result[0]->number_occurence;
}

Nous pouvons donc maintenant modifier notre fonction "modifyArticle" afin qu’elle affiche X fois le texte défini en base :

function modifyArticle($content = '') {
   global $wpdb;
   $tableName = $wpdb->prefix . 'customtext_option';
   $sql = $wpdb->prepare('SELECT number_occurence, textToDisplay FROM ' . $tableName);
 
   $result = $wpdb->get_results($sql);
   $nbOccurence = $result[0]->number_occurence;
   $texteToDisplay = $result[0]->textToDisplay;
 
   for ($i = 0; $i < $nbOccurence; $i++) {
      $content .= $texteToDisplay;
   }
 
   return $content;
}

Il faut également modifier la fonction qui traite les données définies dans l’espace d’administration afin de stocker ces données dans la base de données et non dans les options.

 function displayPageAdmin() {
   global $wpdb;
   $tableName = $wpdb->prefix . 'customtext_option';
 
   $querySelect = $wpdb->prepare('SELECT textToDisplay, number_occurence, MIN(id) AS minId FROM wp_customtext_option');
   $result = $wpdb->get_results($querySelect);
 
   $idLine = $result[0]->minId;
   $data = array(
      'number_occurence'  => $result[0]->number_occurence,
      'textToDisplay'     => $result[0]->textToDisplay
   );
 
   if (isset($_POST['wp_customtextOptionUpdate'])) {
      $data = array();
      if (!empty($_POST['displayText'])) {
         $data['textToDisplay'] = $_POST['displayText'];
      }
      if (isset($_POST['nbOccurences']) &#038;& is_numeric(intval($_POST['nbOccurences']))) {
         $data['number_occurence'] = intval($_POST['nbOccurences']);
      }
      $wpdb->update($tableName, $data, array('id' => $idLine));
   }
 
   echo '<form method="post" action="' . $_SERVER["REQUEST_URI"] . '">
      <label for="displayText">Texte à ajouter à la fin des billets :</label>
      <p><input type="text" name="displayText" value="' . $data['textToDisplay'] . '" /></p>
      <label for="nbOccurences">Nombre de fois :</label>
      <p><input type="text" name="nbOccurences" value="' . $data['number_occurence'] . '" /></p>
      <input type="submit" name="wp_customtextOptionUpdate" value="Mettre à jour" />
   </form';
}

La méthode "get_var" permet de récupérer rapidement une seule variable depuis la base de données.
On s’en sert ici pour récupérer le plus petit id (normalement, il y a une seule ligne dans notre table).

Distribution et publication

Les plugins Worpress peuvent facilement être distribués à la communauté WordPress qui grandit de jour en jour.

Les règles

Votre plugin doit cependant respecter différentes règles :

  • Il doit être open-source
  • Il doit être légal
  • Il doit être hébergé sur le dépôt SVN officiel de WordPress
  • Il ne doit pas contenir de lien pointant vers un site externe sans l’autorisation de la personne qui l’installe

Publication

Pour publier votre plugin WordPress, c'est relativement simple :

  • Créer un fichier readme.txt à la racine du plugin dont la syntaxe est décrite sur la documentation officielle de WordPress
  • Créer un article (par version) sur votre blog, présentant toutes les informations du plugin : à quoi il sert, comment l’installer, comment l’utiliser, comment l’intégrer, les changements entre chaque version (changelog).
  • Inscrivez-vous sur la page officielle d'inscription de WordPress
  • Soumettez votre plugin sur la page de soumission officielle de WordPress
  • Ensuite, vous recevrez (normalement) un mail précisant que votre plugin a été accepté
  • Vous pourrez alors déposer votre code sur le dépôt svn officiel de WordPress.

Conclusion

Ce que nous avons vu dans cet article représente une petite partie de toutes les possibilités offertes par WordPress.
Pour plus d’informations sur la création de plugin, consultez les liens en référence.

Références

  • http://codex.wordpress.org/Writing_a_Plugin
  • http://www.ligams.com/Publications/Wordpress/Plugin-chat-Javascript-pour-Wordpress

Tags: , ,

Un commentaire pour “Créer un plugin Wordpress”

  1. logiciel gratuit tweet adder dit :

    Je suis emerveillé par ce billet , comment creer son propre plugin wp , malheuresement ma connaissance en php et html est insuffisant pour creer mes propre plugins dommage , merci pour les informations de qualités je vais continuer a vous suivre

    amicalement

    david

Laisser un commentaire