1 Plugins wordpress et Plugins wordpressmu:

Transcription

1 Plugins wordpress et Plugins wordpressmu:
Plugins pour Wordpress et WordpressMu
Rédacteur:
Alain Messin (Alain.Messin arobas sophia.cnrs.fr)
CNRS UMS 2202
Admin06
16/01/2009
Le but de ce document est de permettre de débuter rapidement dans la création de Plugins1
pour Wordpress2 3et Wordpressmu4.
Wordpress est un logiciel de Blog assez connu, Wordpressmu en est la déclinaison
permettant d'autoriser la création de blogs par les utilisateurs eux-mêmes (un peu de la même façon
que sur une plate-forme du style blogger ou autre). Il ne s'agit pas ici de débattre des avantages ou
inconvénients de Wordpress par rapport à d'autres logiciels, mais simplement de procurer une prise
en main rapide des éléments divers permettant la réalisation de Plugins (ou extensions en français).
Bien que de nombreux documents soient disponibles5, il manquait à mon sens une synthèse des
mécanismes permettant de mieux comprendre l'ensemble du processus, notamment dans le cas
d'une plate-forme Wordpressmu; c'est ce que tente de faire ce document.
On abordera donc, la constitution des Plugins, les mécanismes d'intégration dans Wordpress
(WP) et Wordpressmu(WPMU), et quelques exemples significatifs. La plate-forme utilisée est la
version française6 de WPMU 2.6.3.
1 Plugins wordpress et Plugins wordpressmu:
Wordpressmu est en fait un emballage de Wordpress permettant la gestion multiblogs. Les
Plugins comme les thèmes sont dans l'immense majorité des cas compatibles entre les deux
versions. Dans les deux cas, il est recommandé de créer des Plugins en cas de besoin spécifiques,
plutôt que de modifier le code des logiciels: les mises à jour en seront largement facilitées, dans la
majorité des cas le Plugin ne sera pas impacté par une mise à jour, ou les modifications à y apporter
seront légères et plus circonscrites que si l'on modifie différents sources du code d'origine.
A noter toutefois qu'il est possible dans le module d'administration de Wordpressmu
d'autoriser ou non l'adjonction de Plugins (cette option étant valable pour tous les blogs).
1.1 ou se trouvent les Plugins:
En général dans les sous-dossiers wp-content/plugins pour Wordpress et Wordpressmu (voir
plus loin), éventuellement dans wp-content/mu-plugins pour Wordpressmu (voir plus loin).
A partir de la version 2.6, les sous dossiers peuvent être spécifiques et sont définis par les
constantes WP_PLUGIN_DIR et MUPLUGINDIR définis (on peut le regretter) par défaut aux
valeurs précédentes, donc relatives au dossier principal (Constante ABSPATH).
Les différents fichiers d'un Plugin peuvent être regroupés pour une meilleure lisibilité dans un sousdossier, mais cela ne fonctionne que dans WP_PLUGIN_DIR, pas dans MUPLUGINDIR.
1
2
3
4
5
6
http://codex.wordpress.org/Writing_a_Plugin
http://wordpress.org/
http://fr.wordpress.org/
http://mu.wordpress.org/
http://codex.wordpress.org/
http://www.wordpress-fr.net/category/blog/wordpress-mu
Plugins pour Wordpress et Wordpressmu
1/8
1.2 de quoi sont constitués les Plugins
Un Plugin est constitué au minimum d'un source php, dont le nom doit être unique parmi
tous les noms de fichiers de la plate-forme, y compris les Plugins qui pourront être éventuellement
utilisés un jour... Donc il faut de l'imagination! Ce fichier est le seul à être reconnu par le logiciel,
les autres fichiers pouvant exister (css, autre php, images etc..) doivent être référencés depuis ce
source.
Si le Plugin est déposé dans un sous-dossier de WP_PLUGIN_DIR, le nom du sous-dossier
n'a pas besoin d'être identique au nom du fichier (sans le .php), mais c'est cependant préférable pour
une meilleure lisibilité. Le contenu minimal du fichier php est, outre le<?php, un commentaire
définissant le nom complet du Plugin. Exemple:
wp-content/Plugins/monPlugin/monPlugin.php
avec monPlugin.php contenant
<?php
/*
Plugin Name: Mon beau Plugin
*/
A noter que pour les Plugins situés dans MUPLUGINDIR, tous les fichiers php seront
considérés comme Plugins (voir plus loin).
1.3 activation et désactivation
Le script php ci-dessus suffit pour que le Plugin soit reconnu dans les extensions de Wordpress, et
activable:
Et une fois activé:
Dans une configuration Wordpressmu, un Plugin placé dans WP_PLUGIN_DIR se
comportera comme indiqué ci-dessus; il sera donc activable/désactivable blog par blog.
Il est souvent souhaitable dans une plate-forme d'activer des Plugins pour tous les blogs,
sans que l'administrateur d'un blog puisse le désactiver. C'est le but du dossier WP_PLUGIN_DIR;
Plugins pour Wordpress et Wordpressmu
2/8
les Plugins présents dans ce dossier seront automatiquement activés (ou plutôt exécutés) pour tous
les blogs, et n'apparaitront donc pas dans le menu de gestion des extensions des blogs; ce mode
d'activation sera donc très différent de celui des Plugins « normaux », on le verra plus loin..
2 Comment ça marche ?
2.1 découverte des Plugins
Lorsqu'on a installé le script php du Plugin dans le dossier WP_PLUGIN_DIR, le
chargement de la page « admin extension » effectue la découverte des nouveaux Plugins, en
cherchant la définition d'un Plugin dans les scripts php. De ce fait, le Plugin sera reconnu, mais non
actif et non exécuté. Il apparaitra donc dans la liste des extensions inactives (voir plus haut).
Les fichiers php présents dans MUPLUGINDIR seront inclus (include_once) à chaque
chargement de page.
2.2 activation et désactivation
On a vu qu'un Plugin reconnu dans WP_PLUGIN_DIR peut être activé, puis désactivé, pour
chaque blog. Cet état perdure, l'état actif ou inactif étant mémorisé dans la table d'options du blog,
$wpdb->prefix.'options', $wpdb->prefix étant le préfixe complet des tables. Le préfixe de tables par
défaut $table_prefix (en général wp_) définit dans wp-config-sample.php), pour WP, est complété
par le numéro du blog (1 pour le blog principal) pour WPMU ) , le nom de la table d'options du
blog 2 étant par exemple wp_2_options si $table_prefix est 'wp_', $wpdb->prefix sera alors 'wp_2_'
pour le blog 2.
La liste des blogs actifs se trouve dans la colonne active_plugins, qui contient un tableau
sérialisé des Plugins actifs, sous la forme des chemins d'accès (relatif au dossier des Plugins) et du
nom du script php principal (ici: monPlugin/monPlugin.php).
A chaque chargement de page, les scripts php des Plugins définis comme actifs pour le blog
considéré sont inclus dans le script général (et donc exécutés), avant toute action. Si le fichier
principal n'est pas trouvé, est corrompu ou lors d'une erreur de chargement, le Plugin est désactivé.
Lors de l'activation d'un Plugin par l'interface d'administration, le script php du Plugin est
également exécuté par un include.
Dans le cas d'une installation WPMU, le fonctionnement est différent pour les Plugins
installés dans le dossier MUPLUGINDIR. En effet, comme indiqué plus haut, les scripts php de ces
Plugins sont inclus dans le script général, avant l'inclusion des scripts Plugin de blogs, et ceci sans
autre forme d'activation. On voit donc que ces Plugins sont actifs, bien que non « activés ». Ils ne
sont donc pas mémorisés comme Plugins actifs dans les tables options. On pourrait plutôt parler de
fichier d' includes optionnels que de réels Plugins.
Les exécutions par les includes décrits ci-dessus sont les seuls moments ou le script php d'un
Plugin est directement exécuté.
Le fonctionnement des Plugins par include montre bien le besoin d'unicité des noms, non
seulement des Plugins, mais aussi de toutes les fonctions et/ou variables définis dans ces Plugins,
vis à vis de l'ensemble des scripts du logiciel.
Pour vérifier le comportement décrit ci-dessus, il suffit d'ajouter un script d'alerte javascript
dans des fichiers de Plugins, et de charger une page. Selon le dossier, le Plugin sera exécuté pour
tous les blogs, ou seulement pour le ou les blogs ou il aura été activé au préalable
echo '<script> alert("mon beau Plugin"); </script>';
Plugins pour Wordpress et Wordpressmu
3/8
2.3 appels aux Plugins
Par appel aux Plugins, on entend appels aux fonctions définies dans les Plugins, étant bien
précisé ci-dessus que l'exécution par include du fichier n'est effectué qu'au moment du chargement
de la page ou de l'activation du Plugin (pour les Plugins situés dans WP_PLUGIN_DIR). En
général, on ne souhaite pas, ou pas seulement, que le Plugin ne serve qu'à ce moment. Toutes les
actions ultérieures doivent donc être définies à cette étape; on peut trouver une certaine similitude
avec le chargement d'un script javascript et l'initialisation des gestionnaires d'évènements (onclick
etc..).
On va expliciter ci-dessous les mécanismes permettant les interactions entre votre Plugin et
WP/WPMU:
2.3.1 Captain Hook!
Les « hooks » (crochets en bon français), sont les dispositifs d'interface de programmation7
permettant de lier les Plugins (et les thèmes/skins d'ailleurs) au fonctionnement de WP/WPMU (le
terme « hook » est également utilisé pour d'autres logiciel comme Drupal ou autres). L'idée étant
qu'il faut éviter de toucher au cœur d'un logiciel pour minimiser les problèmes liés aux bugs, aux
mises à jour, mais qu'on n'est jamais satisfait des fonctionnalités standards et qu'on veut pouvoir en
ajouter. On va donc permettre aux développeurs d'exécuter leur propre code, lors du déroulement du
code du logiciel original, généralement lors de divers évènements. Plus les crochets sont nombreux,
plus l'adaptabilité acquise grâce aux extensions sera grande, mais plus l'évolution du cœur du
logiciel sera délicate; il faut en effet s'efforcer de garder la compatibilité des extensions d'une
version à l'autre du cœur du logiciel. La définition des crochets devra donc être aussi stable que
possible à travers les versions.
Dans WP/WPMU, les crochets sont de deux types: les actions et les filtres; les actions
permettent comme leur nom l'indique de déclencher des actions, les filtres permettant eux de
modifier des contenus.
Lors de l'exécution de l'étape ou se trouve défini le crochet, les actions ou filtres définis pour
ce crochet sont exécutés; on va donc exécuter ce que votre Plugin aura défini pour ce crochet, lors
de son chargement et/ou son activation/désactivation, ou exécution partielle. Plus concrètement, on
va aborder des exemples pour les deux cas, actions ou filtres, mais il faut d'abord aborder les outils
de manipulation de ces actions, filtres et Plugins.
2.3.2 les fonctions liées aux Plugins
Un grand nombre de fonctions8 constituant le cœur du logiciel WP/WPMU sont disponibles
aux développeurs pour permettre à leurs Plugins ou Thèmes d'inter-agir avec celui-ci. Il n'est pas
dans le propos de cet article de détailler ces fonctions, on en abordera quelques unes dans les
exemples de réalisation de Plugins ci-dessous. Cependant un groupe de fonctions est directement lié
à notre besion, ce sont les fonctions du groupe « Action, Filter and Plugin Functions ». Elles ne sont
pas nombreuses, on va donc toutes les décrire brièvement:
●
add_filter: ajoute un filtrage à exécuter sur un crochet de type filtre
●
apply_filters: exécute les filtrages liés à un crochet de type filtre, ou crée un nouveau
crochet de type filtre (utile pour créer des crochets dans les Plugins/Thèmes)
●
merge_filters: ajoute les filtrages liés à un crochet de type filtre aux filtrages exécutés pour
tous.
7 http://codex.wordpress.org/Plugin_API
8 http://codex.wordpress.org/Function_Reference
Plugins pour Wordpress et Wordpressmu
4/8
●
remove_filter: enlève un filtrage lié à un crochet de type filtre.
●
add_action: ajoute une action à un crochet de type action.
●
do_action: crée un crochet de type action (utile pour créer des crochets dans les
Plugins/Thèmes)
●
did_action: retourne le nombre d'activations d'un crochet de type action (depuis le début du
chargement de la page).
●
do_action_ref_array: variante de do_action (paramètres passés en tableau).
●
remove_action: supprime une action d'un crochet de type action.
●
plugin_basename: extrait le nom du fichier du Plugin du nom complet (enlève
éventuellement le nom du dossier éventuel du Plugin, car c'est le nom complet qui est stocké
dans la table options, comme vu en 2.2).
●
register_activation_hook: permet de définir les actions réalisées lors de l'activation d'un
plugin (WP). Equivalente à add_action(activate_(plugin_file)..., voir plus loin.
●
register_deactivation_hook: idem précédente, mais pour la désactivation.
On voit que ces fonctions, appelées dans le script du Plugin, permettent de définir les actions
et les filtres qui devront s'exécuter au moment du crochet correspondant.
Exemple:
<?php
/*
Plugin Name: Mon beau plugin
*/
// fonction executee lors de l'activation du plugin
function activate_monplugin() {
update_option('blogdescription',get_option('blogdescription').' En Travaux!');
}
// fonction executee lors de la desactivation du plugin
function deactivate_monplugin() {
update_option('blogdescription',substr(get_option('blogdescription'),0,-strlen(' En
Travaux!')));
}
// fonction executee lorsque le plugin est actif
// cette fonction ajoute un texte a la fin d'un article avant son affichage
function ajoute_texte($content) {
return $content.'document fini';
}
// les trois instructions, ci-dessous, executees lors de l'include du plugin
// permettent de definir les actions du plugin
register_activation_hook('monplugin/monplugin.php', 'activate_monplugin');
register_deactivation_hook('monplugin/monplugin.php', 'deactivate_monplugin');
add_filter('the_content', 'ajoute_texte');
Explications:
Le commentaire du début définit le nom du Plugin, et permet sa reconnaissance dès celui-ci
Plugins pour Wordpress et Wordpressmu
5/8
positionné dans le dossier WP_PLUGIN_DIR, comme expliqué en 1.2. Le Plugin peut donc être
activé et désactivé dans l'interface d'administration.
On trouve ensuite la définition des fonctions:
●
activate_monplugin(): fonction que l'on veut appeler lors de l'activation du plugin. cette
fonction va modifier la description du blog en ajoutant 'En Travaux' à la suite. Cette
description est stockée dans la table des options du blog (voir plus haut). On utilise les
fonctions de manipulation des options update_option (pour positionner) et get_option pour
lire.
●
deactivate_monplugin(): fonction que l'on veut appeler lors de la désactivation du Plugin, et
qui va remettre la description du blog à sa valeur normale.
●
ajoute_texte($content): fonction qui va ajouter au contenu qui lui est transmis un texte (ici
document fini). On voudra en effet ajouter ce texte à tous les documents (pages ou articles)
affichés.
Enfin, les trois dernières instructions, exécutées lors de l' include du fichier (c'est à dire, lors
de l'activation ou au chargement des pages lorsque le plugin est activé), permettront de définir les
crochets pour lesquels nos fonctions vont devenir actives:
●
register_activation_hook('monplugin/monplugin.php', 'activate_monplugin'): va permettre
d'exécuter la fonction activate_monplugin lors de l'activation du plugin (notez le nom
complet du plugin, avec le dossier). Cette fonction est équivalente à:
add_action('activate_monplugin/monplugin.php', 'activate_monplugin');
mais l'ambigüité sur le chemin du Plugin fait qu'il a été jugé préférable d'ajouter des
fonctions spécifiques pour l'activation et la désactivation des Plugins.
Notons, que dans le cas présent, le update_option aurait pu être positionné en tant
qu' instruction indépendante, puisqu'on désire l'exécuter lors de l'activation, et que le Plugin
est justement exécuté lors de l'activation. Les register_activation_hook et
register_deactivation_hook sont surtout utilisés pour (ré-)initialiser des tables ou données en
table.
●
register_deactivation_hook('monplugin/monplugin.php', 'deactivate_monplugin'): va
permettre l'action inverse lors de la désactivation du plugin.
●
add_filter('the_content', 'ajoute_texte'): permet d'exécuter la fonction d'ajout de texte pour le
crochet 'the_content', correspondant à la disponibilité en argument de la fonction exécutée
du contenu des pages/articles affichées. Cet ajout sera donc effectif durant toute la durée
d'activation du Plugin.
2.3.3 les crochets de type actions
Au contraire des fonctions précédentes, les crochets de type action sont très nombreux9. On
va ici donner juste quelques exemples:
●
pour mémoire, activate_(plugin_file_name) et le symétrique de_activate... dont on a déjà vu
qu'il vaut mieux ne pas les utiliser
●
pour rester dans les plugins, l'intéressant plugins_loaded activé à la fin du chargement de
tous les Plugins. Ce crochet est particulièrement utile pour compléter corriger les actions des
Plugins une fois chargés. Par exemple, on peut ainsi forcer des options indépendamment des
valeurs fixées par certains plugins (on le verra dans l'exemple final).
9 http://codex.wordpress.org/Plugin_API/Action_Reference
Plugins pour Wordpress et Wordpressmu
6/8
●
add/edit/delete_category: activés lors de l'ajout édition ou suppression d'une catégorie
●
save/edit/publish/delete/_post: activés lors de l'enregistrement, édition,publication,
suppression d'un article ou d'une page.
●
get_header/footer: activés par un thème lors de la génération des header/footer
●
loop_start/loop_end: crochets activés au début/ à la fin de la boucle d'affichage des
contenus.
●
wp_login/wp_logout: login ou logout d'un utilisateur.
●
...
2.3.4 les crochets de type filtre
Comme les crochets de type action, les crochet de type filtre sont très nombreux10. On a vu
le crochet 'the_content', utile pour modifier le contenu affiché d'un article. Quelque autres exemples
ci-dessous:
●
sanitize_title: appliqué à un titre d'article/page après filtrage des balises HTML.
●
the_title: idem mais juste après acquisition depuis la base de données.
●
the_content_rss: idem « the_content », mais avant inclusion dans un flux RSS.
●
content_save_pre: appliqué aux contenus avant stockage en base.
●
comment_text: appliqué à une commentaire avant affichage.
●
pre_comment_content: appliqué au contenu d'un commentaire avant stockage en base.
●
get_category: appliqué à l'information de catégorie.
●
wp_list_categories: appliqué à laliste HTML des catégories.
●
attachment_link: appliqué au calcul du lien permanent.
●
get_comment_date/time: appliqué à la date/temps formaté d'un commentaire.
●
get_comment_author_email: appliqué à l'adresse email de l'auteur d'un commentaire après
lectures depuis la bas de données.
●
template: appliqué au template sélectionné.
●
...
3 Exemple de Plugin WPMU
Pour illustrer l'intérêt des Plugins WPMU, on donnera l'exemple très simple, mais
fonctionnel ci-dessous:
●
soit une plate-forme de blogs WPMU à usage des personnels d'un organisme.
●
différents webmasters créent leur propre blog, ils disposent donc d'une autonomie dans
l'administration et la publication sur ces blogs.
●
pour autant, la direction de l'organisme désire que les options de commentaires soient les
mêmes dans tous les blogs.
●
le paramétrage des blogs étant laissé à la discrétion des webmasters, il est possible que l'un
ou l'autre positionne mal les paramètres ou que des Plugins les modifient.
10 http://codex.wordpress.org/Plugin_API/Filter_Reference
Plugins pour Wordpress et Wordpressmu
7/8
Pour répondre à la question, on va créer un petit Plugin WPMU, qui se chargera, une fois
tous les autres Plugins chargés, de ré-initialiser les paramètres selon ceux du blog principal. Pour
cela, il suffit donc d'ajouter dans le dossier MUPLUGINDIR (wp-content/mu-plugins en général)
le petit script ci-dessous.
On utilisera notamment la classe $wpdb11 qui permet les manipulations des tables de la base
de données, et les fonctions de gestion des options.
<?php
/*
A noter qu'il s'agit d'un plugin WPMU, donc le nom du plugin n'a pas
a etre defini formellement dans l'entete
Mention de l'Organisme
*/
// le blog principal est le 1
// les infos sont a recopier pour chaque blog
function recopie_options() {
global $wpdb;
// $wpdb->prefix donne le prefixe pour le blog courant = prefixe_N_
// suppose que _ present
$pfx1=substr($wpdb->prefix,0,strpos($wpdb->prefix,'_')-strlen($wpdb->prefix)).'_1_';
// pour lire les options comments_... on utilise une requete sur la table options
$qry='select option_name, option_value, autoload from '.$pfx1."options where
option_name like 'comments_%'";
$res=$wpdb->get_results($qry,ARRAY_A); // retourne tableau associatif
if (!is_array($res)) $res=array(); // si pas de resultats
foreach ($res as $r) {
// pour chaque option lue du blog principal, on la recopie dans le blog en cours
if ( get_option($r['option_name'])!==false ) {
update_option($r['option_name'], $r['option_value']);
} else {
add_option($r['option_name'], $r['option_value'], '', $r['autoload']);
}
}
}
// l'instruction ci-dessous, executee lors de l'include du plugin
// permet de definir l'actions du plugin
add_action('plugins_loaded','recopie_options');
On est ainsi certain que les options voulues seront conformes.
4 Conclusions
On n'a pas abordé ici tous les détails, notamment l'internationalisation12, l'ajout de menus
d'administration13 pour les Plugins ou la gestion des scripts Ajax14, mais on espère par ce petit
document avoir aider à la compréhension de l'écriture des Plugins pour WP/WPMU.
11
12
13
14
http://codex.wordpress.org/Function_Reference/wpdb_Class
http://codex.wordpress.org/Writing_a_Plugin#Internationalizing_Your_Plugin
http://codex.wordpress.org/Adding_Administration_Menus
http://codex.wordpress.org/AJAX_in_Plugins
Plugins pour Wordpress et Wordpressmu
8/8