Wikini

DocDeveloppeurWikiNi05EcrireUneAction

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-44-220-251-236.compute-1.amazonaws.com

Cette page est destinée aux développeurs découvrant WikiNi et désirant ajouter des fonctionnalités à WikiNi. Elle nécessite une connaissance basique de php et des notions de programmation objet en php. Écrire une action pour WikiNi est relativement facile.
Cette page concerne les versions 0.5.x de WikiNi qui permet une gestion orientée-objet des actions. Pour le modèle d'action des versions <= 0.4.x (qui reste compatible avec le modèle 0.5), consultez cette page.

Présentation

WikiNi possède deux types de greffons ("plugin") :
Nous parlons ici des "actions". Leur syntaxe est toujours la même :
{{nomdelaction param1="valeur1" param2="valeur2"}}
ou un version simplifiée:
{{nomdelaction/param="valeur"}} ou même {{nomdelaction/mode}}"
Les paramètres peuvent être optionnels et les valeurs des paramètres sont toujours entre guillemets.
L'appel d'une action se fait généralement dans le corps d'une page et son résultat éventuel s'affiche à l'endroit où elle a été appelée.

Installation

Pour installer une action, il suffit de placer le fichier php qui la définit dans le répertoire indiqué par le paramètre de configuration "action_path" (voir le fichier wakka.config.php). Une action doit posséder un nom composé uniquement de lettres minuscules et de chiffre. Le fichier dans lequel elle doit se trouver porte le nom de l'action suivi de .class.inc.php afin de la distinguer des actions 0.4.x dont les fichiers finissent simplement par .php.

Comment ça marche ?

Lorsque le formateur WikiNi qui traduit le texte avec les balises WikiNi en HTML rencontre la balise {{ ..... }} il appelle la méthode Action() de l'objet $wiki. Cette méthode récupère les paramètres de l'action puis cherche l'objet qui sert à représenter cette action. Si l'action n'a pas encore été chargée, le moteur va chercher la classe définissant l'action dans son fichier, et en crée une instance. C'est cette instance (un objet de cette classe) qui servira ensuite pour tous les appels de l'action.
Une fois l'objet trouvé, la méthode Action() va appeler la méthode PerformAction de cet objet, en lui passant comme premier paramètre un tableau contenant tous les paramètres de l'action indexés par leur nom.

Écriture de l'action

1. Contrôler que l'action est bien appelée par WikiNi

Une action est appelée par le noyau de WikiNi (/wakka.php) et personne ne doit pouvoir, par mesure de sécurité, l'appeler en direct. En d'autres termes, le lien http://example.org/wikini/actions/mon_action.class.inc.php doit donner une erreur (même si son exécution ne produit normalement rien). C'est pourquoi il est important d'ajouter au tout début de chaque action :
if (!defined("WIKINI_VERSION"))
{
}
Par exemple, le lien suivant devrait donner un tel résultat :
http://www.wikini.net/actions/include.php [AFaire: mettre à jour le lien pour montrer la même chose avec une action 0.5]

2. Implémenter/Étendre la classe WikiniAction

Pour écrire une action WikiNi sous forme d'objets, il faut respecter plusieurs spécifications. En plus du nommage correct du fichier qui contiendra l'action, il faut définir une classe PHP dont le nom est Action suivi par le nom de l'action (avec éventuellement des majuscules dedans, PHP est insensible à la casse des noms de classes, contrairement aux noms de fichiers).
Cette classe doit également la classe WikiniAction fournie dans le fichier /includes/action.class.inc.php. Le noyau se charge automatiquement d'inclure ce fichier dès que cela est nécessaire, donc il est inutile de vous en soucier. Ajoutez simplement après le nom de votre classe, extends WikiniAction. On aura donc par exemple:

3. Constructeur

Comme toute classe, votre classe doit implémenter un constructeur, c'est à dire une méthode spéciale qui porte le même nom que votre classe et qui est appelé lorsque l'on crée un nouvel objet. Votre constructeur doit prendre un seul paramètre (, mais il n'est pas important de comprendre comment cela fonctionne), qui est l'objet $wiki lui-même et vous permettra donc d'avoir accès à toutes les méthodes du noyau. Tout ce que vous avez à faire est de transmettre ce paramètre à la classe parent (c'est à dire WikiniAction) qui en a également besoin, elle sauvera cet objet dans $this->wiki. Vous aurez donc alors un fichier qui ressemblera à ceci:
<?php
if (!defined("WIKINI_VERSION"))
{
  die (
"accès direct interdit");
}
class 
ActionTest extends WikiniAction
{
    
/* variables d'instance */
    
    // constructeur
    
function ActionTest(&$wiki// <-- notez bien le & !
    
{
        
parent::WikiniAction($wiki);
        
/* placer ici d'éventuelles initialisations de variables d'instance */
    
}
    
/* autres méthodes ... */
}
?>

4. Traitement d'un appel de l'action

L'objectif principal d'une action est bien évidemment de pouvoir être appelée depuis une page, avec différents paramètres. Lorsqu'une page appelle une action, le moteur de wiki va récupérer l'objet qui la représente, et appeler sa méthode PerformAction que vous devez implémenter. Cette méthode prend comme premier paramètre un tableau contenant tous les paramètres fournis dans la page, et doit renvoyer une chaîne de caractères contenant le résultat de l'action. Nous allons ignorer le second paramètre pour l'instant car il concerne une gestion plus avancée des actions.
Pendant le traitement de l'action, vous pouvez effectuer tout ce que vous voulez, et vous avez accès à l'ensemble des méthodes de la classe wiki puisque vous disposez d'une référence vers celle-ci dans la variable $this->wiki. Pour ne pas avoir à recopier à chaque fois $this->wiki, vous pouvez créer un alias de cette variable comme ceci:
L'utilisation de $wiki sera alors exactement identique à $this->wiki.
Le reste du code de l'action dépend de son concepteur. Il est important d'avoir parcouru le code de la classe Wiki qui contient de nombreuses fonctions utiles, notamment de mise en forme, de récupération d'information sur l'utilisateur (comme la liste de control d'accès (acl) par exemple) et d'accès à la base de données.
Vous pouvez définir à l'intérieur de votre classe toutes les méthodes et variables d'instances que vous souhaitez. Le wiki travaillant toujours avec la même instance de votre classe (au cours d'un même affichage), il vous est donc possible de mémoriser en variables d'instance des valeurs qui seront transmises entre deux appels de votre action.
Dans le fichier de votre action, vous pouvez également définir d'autres classes et d'autres fonction, tant que vous faites attention à ce que leur nom ne soit pas en conflit avec ceux utilisés par le noyau et dans les éventuels autres modules. (Pour l'instant il s'agit surtout de la classe wiki: vous ne pouvez pas définir une classe qui porte ce nom). Comme votre fichier ne sera chargé qu'une fois, vous ne devez pas vérifier si les fonctions et les classes que vous définissez existent déjà. Vous avez également tout à fait le droit de faire des inclusions d'autres fichiers si nécessaire. (attention: si vous souhaitez inclure un autre fichier de définition de classes et de fonctions, nous vous conseillons d'utiliser la fonction php require_once).
Si votre action doit interagir avec une autre action, faites attention à la façon dont vous manipulez ces objets (cf note ci-dessous).

Exemple d'action

Nous allons ici développer une petite action pour illustrer ce que nous avons dit précédemment. Cette action va simplement afficher le nom d'une page qu'elle reçoit en paramètre.
[code à contrôler]
<?php
// N'oubliez pas non plus, si vous le souhaitez, de mentionner la licence.
// Contrôle pour être sûr que l'action est bien appelée par WikiNi
if (!defined("WIKINI_VERSION"))
{
    die (
"accès direct interdit");
}
// Définition de la classe de notre action
class ActionGetPageOwner extends WikiniAction
{
    
/* définition de variables d'instance:
     * var $nom;
     * etc. (aucune nécessaire ici)
     */
    // constructeur
    
function ActionGetPageOwner(&$wiki)
    {
        
parent::WikiniAction($wiki);
        
/* placer ici d'éventuelles initialisations de variables d'instance */
    
}
    function 
PerformAction($args)
    {
        
// pour ne pas avoir à taper chaque fois $this->wiki, on crée un alias de cette variable:
        
$wiki = &$this->wiki;
        
// Si le paramètre page est vide ou non spécifié on affiche "Le paramètre "page" est manquant."
        
if (empty($args['page']))
        {
            return 
$wiki->Format("//Le param&egrave;tre \"page\" est manquant.//");
        }
        
// Sinon on affiche le propriétaire de la page
        
$page $args['page'];
        return 
$wiki->GetPageOwner($page);
    }
}
?>

Gestion avancée

Le modèle objet permet de faire plusieurs choses assez avancées que ne proposait pas l'ancien modèle, en voici quelques exemples:

Convertir une action WikiNi 0.4 en 0.5

Les actions WikiNi 0.4 peuvent être converties en actions WikiNi 0.5 de manière relativement simple, ce qui est très utile si on souhaite faire évoluer une action pour lui faire profiter des avancées apportées par ce nouveau modèle. Pensez cependant que l'ancien modèle est encore beaucoup utilisé (surtout que la version 0.5 est toujours en cours de développement à ce jour - 2006-02-14).
Pour faire cette conversion, il suffit de procéder en plusieurs étapes simples:
  1. Créez le fichier correspondant à votre action selon la convention de nommage définie ci-dessus (nom.class.inc.php)
  2. Placez dans ce fichier la classe qui réalisera le code de votre action (cf ci-dessus) et définissez comme suit la méthode PerformAction($args):
    • $wiki = &$this->wiki;
    • ob_start();
    • /* code de l'ancienne action */
    • return ob_get_clean();
  3. Remplacez toutes les occurences de $this->GetParameter("nom") par une lecture dans le tableau $args reçu en paramètre. C'est à vous de vérifier si les entrées de ce tableau son définies (utilisez pour cela les fonctions php isset ou empty sur les entrées du tableau).
    • Par exemple:
      • $page = $this->GetParameter("page")
      • if ($page) { /* ... */ }
    • devient
      • if (!empty($args["page"])) {
        • $page = $args["page"];
        • /* ... */}
  4. Remplacez toutes les occurences de $this par $wiki.
  5. Testez votre nouvelle action (enlevez l'ancienne pour vous assurer que c'est bien la nouvelle qui est utilisée)

Interagir avec une action

Avec ce nouveau système de gestion des actions il devient possible interagir avec les objets qui les représente. Tout comme avant, il est possible d'appeler la méthode Action() du noyau, mais on peut aussi récupérer l'objet qui représente une action pour effectuer des opérations "spéciales" dessus. Par exemple vous pourriez vouloir qu'une action puisse effectuer un traitement sur certaines données (comme par exemple les mémoriser, ou encore afficher l'entête ou le pied de page) sans que cette opération puisse se faire avec un simple appel de l'action dans la page. Dès lors vous allez définir dans la classe qui définit votre action une méthode de traitement (par exemple processData($mydata)) qui permettra cette interaction. Ensuite, il ne vous restera plus qu'à récupérer l'objet qui représente votre action via la méthode du noyau GetActionObject($name) (qui prend comme paramètre le nom de l'action) et à appeler sa méthode processData.
Ceci peut aussi bien se faire depuis une autre action, un handler, le noyau ou n'importe quel autre module; mais il faut tout de même faire attention à la gestion de ces objets pour éviter les copies et autres bugs. En effet, en Php4, si vous faites:
$action contiendra ensuite une copie de l'objet qui représente votre action. Or vous voulez certainement travailler toujours sur le même objet, dès lors cette instruction doit être modifiée comme ceci:
Dès lors $action deviendra un "alias" de la variable qui stocke l'action dans le noyau. Ceci signifie donc que toute opération effectuée sur $action sera répercuté sur la variable contenue dans le noyau. Vous devez donc faire très attention avec cet alias ! En effet une réassignation de $action comme ceci:
ou même
provoquera également la modification de la variable dans le noyau, et donc la perte de l'objet qui représente votre action. Ceci risque de provoquer des bugs difficiles à retrouver et donc à corriger. Pour éviter cela, vous devez d'abord "déréférencer" l'objet avec la structure de langage unset(), comme ceci:
Pour éviter toutes les erreurs, il vous est donc conseillé d'appeler unset dès que vous n'avez plus besoin de la référence à l'action sur laquelle vous souhaitez travailler.

Le paramètre $command

En plus du paramètre $args, la méthode PerformAction (que vous devez implémenter) peut prendre un second paramètre $command. Ce paramètre correspond à la chaîne complète d'appel de l'action telle qu'elle a été écrite dans la page (sans les accolades {{ et }}). Ceci peut vous être utile dans le cas où vous voudriez travailler avec une action qui prend ses paramètres sous une forme autre que param="valeur". Par exemple on peut imaginer une action qui affiche le texte qu'on lui passe en paramètre (sans qu'il y ait de problème avec les = ou "):
<?php
class ActionDisplay extends WikiniAction {
    function 
ActionDisplay(&$wiki)
    {
        
parent::WikiniAction($wiki);
    }
    
    function 
PerformAction($args$cmd)
    {
        return 
htmlentities(substr($cmdstrlen('display ')));
    }
}
?>

Ainsi, appeler {{display Il a dit que hello="bonjour" !}} affichera bien "Il a dit que hello="bonjour" !" sans qu'il y ait de problème avec le = et les ". Cet exemple peut paraître naïf mais il y a des cas où cela pourrait être bien utile.
--GarfieldFr, CharlesNepote, LordFarquaad
Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]