MiniGriSpip

Petit site de test et de démonstration du squelette MiniGriSpip 1.6...
  • Calendrier
«février 2008»
lun.mar.mer.jeu.ven.sam.dim.
123
45678910
11121314151617
18192021222324
2526272829

Aujourd'hui vendredi 1 août 2014

 2006   2007   2008   2011 
  • Infos
  • Dernière modification :
    Le mercredi 14 décembre 2011
  • Statistiques contenus :
    Articles : 24 -  Brèves : 4
    Commentaires : 212
    Sites : 3 -  Auteurs : 2
  • Statistiques visites :
    Aujourd'hui : 0 -  Total : 118195
  • Article

Balise #TMP

Balise pour les squelettes...

Le samedi 9 février 2008, par FredoMkb

Cette contrib est avant tout un exemple de création d’une balise qui, je l’espère, pourra quand-même rendre service aux Spipeurs...

Bien-sûr, ce n’est qu’un exemple, il est donc fort probable que des améliorations soient souhaitables, voire nécessaires, pour optimiser son fonctionnement, n’hésitez donc pas à faire part de vos remarques et/ou suggestions dans le forum attaché à l’article...

Sommaire

Avant-Propos

Alors, voici le contexte :

  • Imaginons qu’on souhaite mémoriser quelques informations ou données pour être utilisées par la suite...
  • Imaginons aussi qu’on souhaite pouvoir disposer des données mémorisées partout dans les squelettes...
  • Enfin, imaginons qu’on souhaite disposer d’un système suffisamment souple permettant d’ajouter, modifier et supprimer des données...

Bien-sûr, certains diront qu’un tel mécanisme existe déjà, fourni par défaut dans Spip, sous la forme des balises #SET et #GET (voir documentation), mais ces balises sont un peu limités, c’est à dire qu’elles ne fonctionnent pas dans toutes les situations...

En effet, si on mémorise une variable à l’intérieur d’un squelette, les squelettes inclus (les "noisettes" donc) n’auront pas acces aux données des ces variables, ce qui peut s’avérer un peu embêtant dans certaines circonstances...

Il était donc peut-être intéressant de pouvoir disposer d’un système capable de fonctionner dans ce type de situations, c’est donc le rôle de cette balise #TMP (pour "tampon" ou "temporaire").

Attention !

Au même titre que les balises #SET et #GET, cette balise #TMP n’aura aucun effet dans une boucle si la valeur à récupérer a été mémorisée dans la partie optionnelle de la même boucle. Ce comportement est dû au mode de fonctionnement des boucles Spip.

En effet, les parties optionnelles des boucles sont analysées et traitées après la partie principale de la boucle, et seulement si cette dernière retourne au moins une valeur, autrement dit, si la boucle principale ne retourne aucune valeur, les perties optionnelles ne seront pas considérées.

Utilisation

Passons à l’utilisation de la bête avant d’ouvrir le capot et d’examiner le moteur.

Voici toutes les utilisations possibles et leur syntaxe :

- Mémoriser une Valeur

Deux méthodes pour mémoriser une valeur, soit en passant par la balise #TMP, soit en passant par le filtre |tmp.

La balise #TMP sert surtout à mémoriser des données libres, c’est à dire toute information non fournie par Spip, alors que le filtre |tmp est plutôt dédié à la mémorisation des données générées par Spip (les balises), ce que la balise #TMP ne permet pas. [1]

  • Avec la balise #TMP :

Si par exemple on souhaite mémoriser la valeur "Coucou les amis..." sous la clé "coucou", voici comment faire :

[(#TMP{coucou,'Coucou les amis...'})]

Dans cette méthode, la première valeur fournie est donc la clé d’identification sous laquelle les données seront mémorisées, puis la deuxième valeur est la donnée elle même (la syntaxe de cette balise est donc exactement la même que celle de la balise #SET de Spip).

  • Avec le filtre |tmp :

Le filtre ne permet pas, par défaut, de mémoriser des données libres, ceci est plutôt le rôle de la balise, mais le filtre |tmp est nécessaire pour mémoriser des données générées par Spip (les balises donc).

Si on souhaite par exemple afficher la date du jour à l’intérieur d’une boucle (ARTICLES) (c’est juste un exemple hein ;-)), on ne pourrait pas utiliser la balise #DATE de Spip, puisque cette balise retourne une valeur différente suivant le contexte, dans notre cas c’est la date de publication de l’article qui serait affichée et non pas la date du jour...

Pour y arriver, le filtre |tmp peut nous être utile, en mémorisant la date du jour, sous la clé "today" par exemple, avant le code de la boucle (ARTICLES), avec la syntaxe suivante :

[(#DATE|tmp{today})]

Dans cette méthode, la première valeur fournie au filtre, la balise #DATE donc, est la donnée à mémoriser, et l’argument fourni au filtre entre les accolades, {today}, est la clé sous laquelle la date du jour sera conservée.

- Récupérer une Valeur

Pour retrouver une valeur mémorisée, rien de plus simple, la balise #TMP s’utilise de la même manière que son homologue #GET de Spip, avec la syntaxe :

[(#TMP{coucou})]

Cet exemple retournera notre "Coucou les amis...". Autrement dit, il suffit de fournir, comme argument a la balise, la clé sous laquelle l’information a été enregistrée, quelque soit la méthode de mémorisation utilisée, par balise ou par filtre.

Notre second exemple retournera la date du jour au moment de la mémorisation de la valeur :

[(#TMP{today})]

- Valeur par Défaut

Il peut être pratique de disposer d’une valeur par défaut à utiliser si la variable demandée n’est pas ou n’est plus disponible, ceci est possible de la manière suivante :

[(#TMP{coucou,'',defaut})]

La syntaxe à respecter nécessite donc de fournir 3 arguments à la balise, dont le premier correspond a la clé des données qu’on cherche à récupérer, le deuxième argument doit être vide, ce qu’on obtient en mettant deux guillemets, ou deux apostrophes, sans aucun contenu entre les deux, enfin, le troisième argument est la valeur par défaut à afficher si la clé du premier argument n’est pas trouvée.

Attention !

La valeur par défaut est une donnée libre, c’est à dire qu’il ne s’agit pas d’une clé servant à extraire d’autres données en mémoire, mais d’une valeur "brute" à afficher tel-quelle si la clé du premier argument est introuvable.

- Modifier une Valeur

Il est aussi possible de modifier la valeur d’une variable déjà en mémoire, il suffit de mémoriser la nouvelle valeur avec exactement la même clé que la valeur originale, ceci fonctionne avec les deux méthodes : balise et filtre.

Suivant notre premier exemple, si au lieu d’avoir "Coucou les amis..." nous souhaitions afficher "Bonjour monde..." à la place, on ferait :

[(#TMP{coucou,'Bonjour monde..'})]

Dès lors, la clé "coucou" retournera cette nouvelle valeur.

- Supprimer une Valeur

Pour ne pas saturer inutilement l’espace mémoire utilisé (voir chapitre "Mécanique") avec des données qui ne sont plus nécessaires, il est possible de supprimer les valeurs obsolètes.

La méthode est très simple, il suffit de fournir deux arguments à la balise #TMP, dont le premier doit être vide et le deuxième correspondre à une clé existante en mémoire.

Par exemple, si on souhaite supprimer notre variable "coucou", il suffit d’utiliser la syntaxe suivante :

[(#TMP{'',coucou})]

Ici on fourni à la balise un premier argument vide, qu’on obtient en mettant deux guillemets, ou deux apostrophes, sans aucun contenu entre les deux, puis on fourni le nom de la clé correspondant aux données à supprimer.

Attention !

Ceci a pour effet de supprimer purement et simplement le couple "clé/valeur" concerné, les données seront donc perdues définitivement.

- Supprimer Toutes les Valeurs

On peut aussi supprimer toutes les données mémorisées en une seule opération, et éviter ainsi de devoir faire autant de suppressions individuelles, épargnant du coup un peu de travail au serveur.

Pour supprimer donc toutes les entrées mémorisées, il suffit d’insérer la balise #TMP toute seule, sans aucun argument, soit :

[(#TMP)]

Attention !

Ceci a pour effet de supprimer purement et simplement toutes les entrées en mémoire gérées par la balise, les données seront donc perdues définitivement.

Résumons

  • Mémoriser une valeur : [(#TMP{cle,valeur})] ou [(#VALEUR|tmp{cle})]
  • Récupérer une valeur mémorisée : [(#TMP{cle})]
  • Valeur par défaut (au cas où) : [(#TMP{cle,'',defaut})]
  • Supprimer une valeur : [(#TMP{'',cle})]
  • Supprimer toutes les valeurs : [(#TMP)]

Mécanique

Le mécanisme mis en oeuvre est relativement simple, voire simpliste aux yeux de certains, mais il a le mérite d’assurer un bon fonctionnement.

Il s’agit donc d’utiliser la variable globale $GLOBALS pour y stocker des données et informations qui seront ensuite récupérées pour être exploités aux endroits souhaités dans les différents squelettes...

D’accord, de l’avis de certains, c’est "mal" d’utiliser cette variable globale un peu pour tout et parfois pour n’importe quoi, mais avouons qu’elle a le grand avantage d’être disponible et facilement accessible sans avoir à sortir la grosse artillerie des sauvegardes en base de données ou dans des fichiers... ce qui aurait été un peu lourd pour des besoins relativement modestes, tels qu’abordés dans cette contrib.

Donc, en gros, pour ceux qui lisent un peu du Php, il s’agit de créer des nouvelles entrées dans la variable $GLOBALS, sous la clé générique ['tmp'], avec la syntaxe suivante :

$GLOBALS['tmp'][$cle] = $valeur;

Pour ensuite être utilisable par :

return $GLOBALS['tmp'][$cle];

Moteur

Voyons donc ce qui se cache sous le capot...

La balise est construite avec trois fonctions Php :

  • La première fonction implémente la balise #TMP elle même, c’est le code appelé par Spip.
  • La deuxième fonction est juste un pont entre le code de la balise #TMP et celui du filtre |tmp.
  • Enfin, la troisième fonction correspond au filtre |tmp, et c’est elle qui gère les accès aux données.

Voici le code complet, avec quelques commentaires :

Installation

Pour éviter d’éventuels problèmes d’encodage du texte, vous pouvez récupérer le code complet en téléchargeant l’archive suivante :

Zip - 2.3 ko
Balise #TMP

Pour installer la balise, utilisez une des deux méthodes suivantes :

- Par Copier/Coller

Éditez simultanément le fichier téléchargé "spip_balise_tmp.php" et le fichier "mes_fonctions.php" qui se trouve dans le dossier "squelettes" de votre site.

Faites un simple copier/coller de l’ensemble du code de la balise, fichier "spip_balise_tmp.php" donc, dans le fichier "mes_fonctions.php", au début ou à la fin du fichier.

Assurez-vous juste de ne pas copier les balises Php <?php et ?> qui se trouvent respectivement en début et fin du code.

- Par Inclusion

Cette méthode est plus simple et donc plus recommandée.

Il s’agit de placer le fichier téléchargé "spip_balise_tmp.php" au même niveau que le fichier "mes_fonctions.php", dans le même répertoire donc.

Il faut ensuite éditer le fichier "mes_fonctions.php" pour y placer, au début (juste après la balise d’ouverture Php), le bout de code suivant :

include('spip_balise_tmp.php');

Dans les deux cas, enregistrez les modifications du fichier "mes_fonctions.php" puis videz le cache de Spip (espace privé => Configuration => Vider le cache).

Limitations

La balise #TMP, en l’état, n’est pas capable de traiter dans ses arguments des valeurs dynamiques, d’autres balises par exemple, il s’agit donc pour l’instant d’une simple balise "statique".

Le filtre |tmp tente de pallier, en partie, à cette restriction de la balise, mais son champ d’action reste assez limité tout de même, puisqu’il n’est pas possible, par exemple, d’insérer du code Html de manière simple et directe (voir chapitre "Astuces").

Enfin, l’utilisation de la variable globale $GLOBALS, pour mémoriser les variables, n’autorise pas la manipulation de grands volumes de données, ni de données aux contenus complexes, il faut donc se limiter à une utilisation modeste, voire basique, de cette solution.

Astuces

- Mini Config

Une idée d’utilisation de cette balise #TMP serait, par exemple, de préparer une "noisette" contenant un ensemble de valeurs à mémoriser, pour qu’elles soient disponibles dans toutes les pages du squelette, un peu comme s’il s’agissait d’un mini système de configuration...

Par exemple, on crée un fichier Html nommé "inc-mini-config.html", dans lequel on insère autant de balises #TMP que des infos à mémoriser, sans aucun autre code Html.

Il suffit d’insérer cette noisette, par un simple #INCLURE (voir encadré ci-dessous), dans le fichier d’en tête du site "inc-head.html", pour avoir toutes ces données accessibles sur l’ensemble des fichiers du squelette.

Bien-sûr, il ne faut pas trop abuser de cette technique, il vaut mieux se tourner vers d’autres solutions de configuration, comme le plugin CFG par exemple, pour disposer d’un système de configuration plus souple et puissant.

Attention !

Spip possède deux mécanismes différents pour inclure des fichiers externes dans un fichier hôte, soit par la balise #INCLURE (depuis Spip 1.9.1) soit par la méthode historique <INCLURE> (voir documentation).

Or, ces deux techniques ne travaillent pas exactement de la même manière, notamment en ce qui concerne la gestion du cache, ce qui restreint l’utilisation de notre balise #TMP à travailler uniquement avec les inclusions de type #INCLURE pour pouvoir bénéficier d’une disponibilité efficace des valeurs mémorisées dans la variable $GLOBALS.

Pour tenter de résumer en deux mots, les fichiers hôte qui travaillent avec la balise #INCLURE génèrent un seul fichier de cache avec les données locales et celles issues du fichier externe, alors que la méthode par <INCLURE> génère autant de fichiers de cache que des fichiers traités, autrement dit, ils ne partage pas forcément le même espace mémoire et donc pas les mêmes données.

Ces remarques ne font que reprendre (d’après ce que j’ai compris) des explications for instructives partagées par Matthieu Marcillaud quant au fonctionnement des inclusions et à l’efficacité relative de cette contrib avec elles, merci à lui pour tout ces éclaircissements.

- Balises et Html

Comme expliqué dans le chapitre "Limitations", la balise n’est pas adaptée à traiter des données dynamiques, et le filtre est incapable en l’état de mélanger des balises Spip a du code Html... voici donc une astuce pour contourner cette restriction.

Il s’agit d’utiliser la balise #REM pour lui forcer à afficher quelque chose (technique expliquée dans l’article "Appliquer un filtre sur autre chose qu’une balise"), puis d’appliquer le filtre sur ce résultat.

Imaginons que nous désirons insérer, un peu partout sur nos squelettes, un lien complet avec l’adresse du site, il peut être sympa de ne pas avoir à mettre toujours le même code Html, voici donc comment mémoriser un tel code afin de l’utiliser autant de fois qu’on le souhaite :

[(#REM|sinon{<a href="#URL_SITE_SPIP" title="[(#DESCRIPTIF_SITE_SPIP|couper{50})]">
<:bienvenue_sur:>#NOM_SITE_SPIP</a>}|tmp{url})]

Petite explication, on force une balise #REM à afficher quelque chose grâce au filtre |sinon (voir documentation), puis on applique notre filtre |tmp en lui fournissant la cle d’identification du contenu à mémoriser.

Comme le montre l’exemple, on peut mettre des balises, des filtres et même des textes localisés entre les accolades du filtre |sinon, mais il ne faut pas trop compliquer le contenu à mémoriser, il n’est pas garanti que Spip puisse gérer de telles acrobaties de calcul avec des codes trop complexes.

Enfin, pour placer ce code dans les squelettes, rien de plus simple :

[(#TMP{url})]

Un petit avantage de cette méthode est que le code Html est calculé une seule fois, puis le résultat est conservé en mémoire en l’état, ce qui permet de l’utiliser autant de fois que souhaité sans avoir à les recalculer.

Avertissements

Comme signalé à plusieurs reprises dans l’article, ne tentez pas d’utiliser cette technique pour des traitements lourds, elle n’est pas adaptée, préférez vous tourner vers de plugins capables d’une meilleur interaction avec Spip.

Enfin, veillez à nommer de manière la plus simple possible vos clés d’identification pour les données à mémoriser, évitez par exemple d’utiliser des caractères accentués ou spéciaux et, dans la mesure du possible, préférez les tirets bas "_" aux espaces pour séparer les différents mots de la clé.

Remerciements

Comme d’hab, à toute la communauté de Spipiens pour toutes leurs contributions, les unes plus enrichissantes que les autres, et aussi, surtout, à tout ceux qui se démènent (jour et nuit) pour développer ce magnifique CMS qu’est SPIP.

Un grand merci à Matthieu Marcillaud pour toutes ces explications à propos des techniques d’inclusion.

Notes :

[1] Ceci est dû au fait que #TMP n’est pas une balise dynamique (ce que je n’aurais pas su réaliser vu mon niveau en développement).

  • Il n'y a aucune image...
  • Il n'y a aucun commentaire...
Suivre la vie du site RSS 2.0 | SPIP | Mgs MGS