Wikini

DiscussionsActionInclude

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-54-166-223-204.compute-1.amazonaws.com

Discussions sur l'ActionInclude


Problème lié à l'utilisation d'un include pour gérer l'interface utilisateur

Nous avons évoqué plus haut la possibilité d'employer l'action include pour laisser le contrôle de l'interface à l'utilisateur ; à ce titre, nous avons pris l'exemple du contrôle du menu de navigation grâce à un include : dans le fichier wakka.config.php, il suffit d'indiquer : "navigation_links" => "{{include page=\"MenuDuHaut\"}}",
Cette possibilité a un effet de bord un peu génant : lorsque l'on affiche la page source, MenuDuHaut dans notre exemple, un message d'erreur est affiché en lieu et place du menu : Impossible à une page de s'inclure dans elle même. Ce message est logique dans le cas d'un include d'une page dans corps même de sa propre page, mais il serait en revanche souhaitable que l'include fonctionne normalement lorsque l'include est réalisé en-dehors du corps de la page. (Suis-je clair ?)
Il existe une solution technique assez simple mais que je ne trouve pas très élégante : dans /handlers/page/show.php il suffit :

Dans /wakka.php : var $page;

Dans /handlers/page/show.php :
// display page


Dans /actions/include.php :
if (strcasecmp($incPageName, $this->GetPageTag?()) and $this->in_page_body) {

NON !!!! Le test est faux, strcasecmp compare des chaine de caratères est renvoie une valeur >0 ou <0 ou =0 selon que la chaine1 est plus grande, plus petite ou égale à la chaine2. Hors ici, si les 2 chaine sont égale strcasecmp renvois 0 est donc le teste deviens faux...
Je préfère la version avec des expressions régulières, mais avec strcasecmp il faudrait plutôt écrire:
if (strcasecmp($incPageName, $this->GetPageTag?()==0) and $this->in_page_body) {

--GarfieldFr
(non testé)


Qu'en pensez-vous ? Voyez vous d'autres solutions ?
-- CharlesNepote

Je ne pense pas que ce soit utile de faire un test sur le fait que l'on soit dans le corp ou l'entête de la page simplement parce que la personne habilité à modifier le menu (ou toutes autre partie de l'interface) est l'administrateur du site et donc doit savoir ce qu'elle fait. Si la documentation de l'action indique que l'inclusion d'une page dans elle même est impossible, et bien le message d'erreur ne lui semblera pas anormal.
-- GarfieldFr

Oui, je confirme. l'utilisateur est roi.C'est la première des priorités :-) -- ThierryBazzanella.

Vers une personnalisation poussée de WikiNi ?


On peut aussi améliorer cette action en ajoutant la possibilité de styler le code produit à l'aide du paramètre "style" : ce dernier permet d'entrer du code CSS de façon équivalente à l'attribut HTML "style" : exemple : {{include page="PagePrincipale" style="font-size: 9px;"}}

Cependant, il existe quelques problèmes de sécurité dus à l'attribut "style". J'ai posé la question dans la liste spécialisé CSS en français ; cf. le fil de discussion suivant :
http://fr.groups.yahoo.com/group/pompeurs/message/4085?threaded=1
Je vais voir comment il est possible d'intégrer l'attribut "style" en filtrant les propriétés CSS passées en paramètre.
-- CharlesNepote

Inclusion d'une page d'un autre WikiNi

Dans la page WikiNiSyndication, DavidDelon parle de recoder l'action include pour faire de la syndication. J'ai codé une telle action include. Maintenant, le nom de la page est soit un URL soit une page WikiNi local. Les syntaxe suivante sont donc valide :
Avec le changement de serveur arrive des problèmes de référence circulaire, cela est géré.
La seule chose qui ne soit pas gérée est le transfert des styles d'un serveur à l'autre, c'est à dire que si la page incluse provient d'un autre WikiNi et que cette page inclus elle même une page avec un certain style, l'affichage pourra être différent.
J'ai déjà testé les références circulaires, mais pas de manière exhaustive. Je n'est pas vérifié si droit de lecture était correctement vérifié, à priori oui car la méthode /raw vérifie les droits de lecture.
Voici le code de l'action pour teste : WikiNiSyndication
--GarfieldFr
Trés bien cette action, le codage de l'ancienne syndication ne me plaisait pas vraiment. Je teste tout cela (éventuellement à partir de la branche CVS de Test si on se met d'accord dessus). -- DavidDelon

Tout ce que je fais de "distribuable à mon avis" se retrouve dans le CVS TEST pour que vous puissiez le tester. Donc la modification de include pour le support de page externe au site est dans le CVS TEST. --GarfieldFr


NOTE


I have been trying to get the ActionInclude to work on the latest (0.1.2) Wakkawiki code. I copied the include.php from the 0.4.1 tar ball and drop it on the /actions directory. I added var $parameter = array(); to the wakka class and added the function GetParameter? as well. Still is not working, even though I am calling it {{include page="HomePage"}} it still says the parameter "page" is missing. Am I missing something? Thanks! --DavidCollantes (http://www.netbros.com/)

You did right in adding $parameter = array() and fonction GetParameter?() in wakka.php, but you should also make these changes in wakka.php near line 330 :

// prepare an array for extract() to work with (in $this->IncludeBuffered())
                        if (is_array($matches))
                        {
                                for ($a = 0; $a < count($matches); $a++)
                                {
                                        $vars[$matches[1][$a]] = $matches[2][$a];
                                        $this->parameter[$matches[1][$a]]=$matches[2][$a];

                                }
                        }
                }
                if (!$forceLinkTracking) $this->StopLinkTracking();
                $result = $this->IncludeBuffered(strtolower($action).".php", "<i>Unknown action \"$action\"</i>", $vars, $this->config["action_path"]);
                $this->StartLinkTracking();
                 if (isset($parameter)) unset($this->parameter[$parameter]);
                 unset($this->parameter);



Peut-on inclure une page d'un autre Wiki ?, d'un autre site ? --FidelioEspoir
Non, cela est impossible. Il s'agit d'inclusion de page WikiNi uniquement car la page incluse est soumise au formatage de Wikini et donc une page google ne peut pas être incluse. Par contre il doit etre possible d'ecrire une action du style {{includeURL URL="http://www.google.com/search?q=contrepeterie"}}. --GarfieldFr
Par contre, avec quelques modifications, il doit être possible d'inclure une page d'un autre WikiNi --GarfieldFr
Idée superbe : tout ce qui permet de densifier les mailles du réseau enrichit WikiNi --FidelioEspoir


Include, page d'aide et MultiWikiNi

Ta fonction est parfaite pour insérer une page constamment actualisée. Lorsque je propose d'ouvrir une nouvelle fenêtre, c'est dans l'optique d'un changement de registre : Texte et Aide sur le texte , Web et meta-Web. L'avantage d'une nouvelle fenêtre permet de ne pas mélanger les deux historiques. On peut ainsi consulter plusieurs pages d'aide tout en restant sur la page étudiée. On peut surtout rester sur la Page Sujet tout en lisant les pages SujetAvisdeX , SujetAvisdeXY ou sur les pages "SujetHier , "SujetDemain . Cela permet en quelque sorte de quitter le Wiki, ensemble linéaire de liens à une dimension, pour un MultiWikiNi. -- FidelioEspoir


Paramètre créant un bouton d'ouverture/fermeture du texte de l'include

Mais, pour te convaincre que je continue à adorer l'action "include", j'aimerais lui voir attacher une petite (!!??) action sous forme d'un bouton (!!???!!) : Fermer/ouvrir l'include. Clic et je lis le texte inséré, clic je le referme. Il suffit de (ah aha ah !) changer le style de l'include te dirait yakataka ! -- FidelioEspoir

Il faut voir : cf. http://www.meyerweb.com/eric/css/edge/popups/demo.html. Je trouve le challenge assez amusant, mais je ne vois pas encore beaucoup d'applications (des idées ?). -- CharlesNepote

Ce site est superbe d'intelligence que... je n'ai pas. J'utilise le css pour seulement changer les couleurs de mon site. Utiliser les CSS au lieu d'un javascript est certainement l'avenir pour le développeur. Mais j'écris toujours ici en tant qu'utilisateur. L'avantage d'une seconde fenêtre est de permettre de continuer à écrire sur une page, tout en continuant à lire l'autre. Mes remarques "informatiques" essayent de me faire mieux comprendre plus vite et surtout de vous convaincre que je partage vos difficultés de prog. Que tu y trouves aussi un plaisir, un amusant challenge me ravit au plus haut point !
En débutant mon site, j'avais mis à gauche une colonne menu permettant à chacun d'aller directement là où il le désire. (idée trouvée ici du côté de l'Afrique ;-) voir ContributionsAvancees ) . Cette solution s'avère éminemment utile pour des sites où les pages se suivent à la queue leu leu. Mon site utilisant une pléthore de liens entre pages, elle s'avère finalement moins nécessaire et surtout elle prenait de la place dans chaque page. J'ai bien essayé de la faire disparaître avec le fameux bouton clic-clac, jour-nuit, en dédoublant mes wakka.css (bleu, jaune vert, marron...) avec leurs sosies où la table-column deviendrait width=0, où le texte serait invisible...J'ai abouti à un carnage : tout était sens dessus dessous, et les liens invisibles fonctionnaient toujours...Je l'ai donc abandonnée au profit d'un include en première page. A moins qu'un malicieux s'empare d'un bouton magique et s'y amuse... tant mieux pour tous !! ;-) --FidelioEspoir

MenuDuHaut suite : création d'un menu personnalisé

Vous avez installé un menu "include". il est possible maintenant d'y ajouter une ligne "menupersonnel" :
Création d'une action menuutilisateur.php que l'on installe dans une page MenuUtilisateur
<?php
/*...
 licence GPL...
*/ 
if ($phrase $_REQUEST["phrase"])
{
    
$phrase trim($phrase);
    
$this->SetPersistentCookie("menu",$phrase,1);
    
$this->Redirect($this->href());
}
echo  
$this->FormOpen("""""get") ;
?>
<table border="0" cellspacing="0" cellpadding="0">
    <tr>
        <td>NomWiki uniquement &nbsp;</td>
        <td><input name="phrase" size="40" value="<?php echo  htmlentities($this->Getcookie("menu")) ?>" /> <input type="submit" value="Menu choisi" /></td>
    </tr>
</table>
<?php echo  $this->FormClose(); ?>

puis dans header.php
....<?php echo  $this->config["navigation_links"] ? $this->Format($this->config["navigation_links"])." \n" "" ?> 
////
<br />  
<a href="<?php echo $this->config["base_url"]?> menuduhaut" ">Menu</a> : 
<?php
//pm
    
$menu htmlentities($_COOKIE["menu"]);
    
$menu explode(" ",$menu);
    
$menupersonel "";
    foreach (
$menu as $nom){
    
$menupersonel $menupersonel $this->Link($nom)." ";
    }
    
$menupersonel rtrim($menupersonel);
    if (!empty(
$menupersonel))  echo  $menupersonel 
?>
<br />
////
.....

et le menupersonel s'inscrit juste après le menuduhaut
Toute amélioration du script est fortement encouragée !
Chaque utillisateur enregistré ou non peut ainsi construire un menu contenant les cartes qu'il fréquente le plus. A l'usage, vous ne pourrez plus vous en passer ! 2004-05-22 -- 18 : 24 -- FidelioEspoir

Question: Pourquoi les images incluses dans une page pointée par un include ne sont pas visibles? StephaneCvr

Suite au bug que j'avais signalé dans les RapportsDeBogues, je propose le code suivant:
Dans la ClasseWiki, ajout d'une variable $inclusions, et ajout des méthodes suivantes:
<?php
    
// inclusions
    /**
    * Enrégistre une nouvelle inclusion dans la pile d'inclusions.
    * @param string $pageTag Le nom de la page qui va être inclue
    * @return int Le nombre d'éléments dans la pile
    */
    
function RegisterInclusion($pageTag){
        return 
array_unshift($this->inclusionsstrtolower(trim($pageTag)));
    }
    
/**
    * Retire le dernier élément de la pile d'inclusions.
    * @return string Le nom de la page dont l'inclusion devrait se terminer.
    * NULL s'il n'y a plus d'inclusion dans la pile.
    */
    
function UnregisterLastInclusion(){
        return 
array_shift($this->inclusions);
    }
    
/**
    * Renvoie le nom de la page en cours d'inclusion.
    * @example // dans le cas d'une action comme l'ActionEcrivezMoi
    * if(strtolower($this->GetPageTag()) != $this->CurrentInclusion())
    *     echo 'Cette action ne peut être appelée depuis une page inclue';
    * @return string Le nom (tag) de la page (en minuscules)
    * FALSE si la pile est vide.
    */
    
function CurrentInclusion(){
        return isset(
$this->inclusions[0]) ? $this->inclusions[0]: FALSE ;
    }
    
/**
    * Vérifie si on est à l'intérieur d'une inclusion par $pageTag (sans tenir compte de la casse)
    * @param string $pageTag Le nom de la page à vérifier
    * @return bool True si on est à l'intérieur d'une inclusion par $pageTag (false sinon)
    */
    
function IsIncludedBy($pageTag){
        return 
in_array(strtolower($pageTag), $this->inclusions);
    }
    
/**
    * @return array La pile d'inclusions
    * L'élément 0 sera la dernière inclusion, l'élément 1 sera son parent et ainsi de suiste.
    */
    
function GetAllInclusions(){
        return 
$this->inclusions;
    }
    
/**
    * Remplace la pile des inclusions par une nouvelle pile (par défaut une pile vide)
    * Permet de formatter une page sans tenir compte des inclusions précédentes.
    * @param array La nouvelle pile d'inclusions.
    * L'élément 0 doit représenter la dernière inclusion, l'élément 1 son parent et ainsi de suite.
    * @return array L'ancienne pile d'inclusions, avec les noms des pages en minuscules.
    */
    
function SetInclusions($pile = array()){
        
$temp $this->inclusions;
        
$this->inclusions $pile;
        return 
$temp;
    }
?>

Nouvelle version de l'action include:
<?php
// récuperation du parametres
$incPageName trim($this->GetParameter('page'));

/**
* @todo améliorer le traitement des classes css
*/
if ($this->GetParameter('class')) {
    
$array_classes explode(' '$this->GetParameter('class'));
    
$classes '';
    foreach (
$array_classes as $c) {
        if(
$c$classes .= ($classes '':' ') . "include_$c";
    }
}

// Affichage de la page ou d'un message d'erreur
if (empty($incPageName)) {
    echo 
$this->Format('//Le param&egrave;tre "page" est manquant.//');
} elseif (
$this->IsIncludedBy($incPageName)) {
    
$inclusions $this->GetAllInclusions();
    
$pg strtolower($incPageName); // on l'effectue avant le for sinon il sera recalculé à chaque pas
    
$err '[[' $pg ']]';
    for(
$i 0$inclusions[$i] != $pg$i++) {
        
$err '[[' $inclusions[$i] . ']] @@->@@ ' $err;
    }
    echo 
$this->Format("//Impossible pour la page '[[$incPageName]]' de s'inclure dans elle m&ecirc;me//"
        
. ($i ":---**Chaine d'inclusions**: [[$pg]] @@->@@ $err"'.')); // si $i = 0, alors c'est une page qui s'inclut elle-même directement...
} elseif (!$this->HasAccess('read',$incPageName)) {
    echo 
$this->Format("//Lecture de la page inclue '\"\"$incPageName\"\"' non autoris&eacute;e.//");
} elseif(!
$incPage $this->LoadPage($incPageName)) {
    echo 
$this->Format("//La page inclue '[[$incPageName]]' ne semble pas exister...//");
} else {
    
$this->RegisterInclusion($incPageName);
    
$output $this->Format($incPage['body']);
    if (isset(
$classes)) echo "<div class=\"$classes\">\n$output</div>\n";
    else echo 
$output;
    
$this->UnregisterLastInclusion();
}
?>
(j'ai utilisé mon propre standard de programmation, vu que les DiscussionsNormeDeCodagePHPPourWikiNi n'ont pas encore abouti...
Je sais que les @ c'est pour barrer du texte, mais cela donne particulièrement bien sur ces flèches, regardez: -> lol à changer, mais bizarrement le gras ne donnait rien chez moi :s)

Il faut aussi modifier les handlers show, edit, slide_show (qui, je pense, devrait être réécrit pour ne plus qu'il formatte tout quand il n'a besoin que d'un morceau...) et diff pour qu'ils ajoutent la page en cours comme première inclusion, c'est assez simple. (si je ne me trompe ce sont actuellement les seuls handlers qui formattent des pages. addcomment ne le fait actuellement pas, mais je trouve qu'il devrait... si vous voulez savoir pourquoi, posez la question dans DevActionsEntetePiedDePageEtLinktracking).
Ce code corrige notemment le "bug" qui affichait un message d'erreur lorsque l'on éditait une page inclue dans l'entête.
J'attends votre avis mais je pense que ça devrait être bon pour le cvs. [Ok en ce qui me concerne. -- ProgFou - Pas d'autres avis ? Dans ce cas je l'ajouterai au CVS demain soir -- LordFarquaad] J'ai fait plusieurs tests chez moi et ils me paraissent très concluants:

Cela affiche bien les messages d'erreur auxquels on s'attend, ainsi que la page ParametresUtilisateur dans les trois pages.

Je n'ai pas fait la modification que propose GarfieldFr dans WikiNiSyndication, car la trouve trop compliquée et restrictive (marche que avec les sites WikiNi qui n'utilisent pas la ReecritureDURL et n'ont changé aucun nom de fichier, paramètre etc.). L'avantage par rapport à [[|url]] me parait donc trop négligeable... Je vais tout de même détailler ce qu'il serait possible de faire:
Pour moi le mieux serait d'ajouter à l'action include un paramètre from dans lequel il faudrait placer une url avec un %s pour répérer l'endroit où insérer les noms de page. Ca donnerait quelque chose de ce genre:
{{include page="MyPostit" from="http://knowledge.martignier.net/wakka.php?wakka=%s/raw"}}.
Le paramètre from pourrait à se moment là accepter tout simplement des références interwiki, en supposant qu'on peut ajouter /raw à tous ceux d'entre eux qui sont des WikiNi (de toute façon on ne saurait pas faire grand chose des autres à part en cherchant les <body...>...</body>... je pense que c'est creusable mais pas pour les intewiki. Ca pourrait être fait en spécifiant une url dans le "page" sans spécifier de from... d'ailleurs ce serait une inclusion bien plus simple et universelle [sauf pour les liens relatifs... -> trop complexe à envisager])
On pourrait aussi envisager un troisième paramètre pour spécifier s'il faut faire les éventuelles inclusions avec des pages locales ou distantes.
Pour éviter les références circulaires, il faudrait, je pense, envisager une pile secondaire (statique) dans l'action include. La méthode RegisterInclusion() pourrait très bien être utilisée pour enrégistrer les urls reconstituées (ex.: http://knowledge.martignier.net/wakka.php?wakka=MyPostit/raw. Le seul problème que cela pourrait poser c'est le cas où deux sites dont les urls ne diffèrent que par leur casse possède des pages du même nom... ça va chercher loin :-j), tandis que la pile statique de l'action include servirait à enrégistrer uniquement les from (et éventuellement la valeur du troisième paramètre) à partir du moment où il y a de la syndication. Il y a juste une chose qui peut poser problème c'est que cette pile statique serait accessible à n'importe quelle action, mais ce n'est pas pire qu'une pile globale...
-- LordFarquaad
Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]