Boucler sur un tableau
On peut boucler arbitrairement sur un tableau tel que ceux renvoyés par les balises suivantes : #ARRAY
, #GET
, #SESSION
, etc.
Boucle sur les données de la session de l’utilisateur connecté :
<BOUCLE_session(DATA){source table,#SESSION}>
#CLE: #VALEUR <br>
</BOUCLE_session>
Boucle sur un tableau contenant des mots défini avec #SET / #GET
[1] :
<BOUCLE_mot(DATA){source table,#GET{mots}}>
#VALEUR
</BOUCLE_mot>
Boucle sur un tableau quelconque contenant des couleurs :
<BOUCLE_couleurs(DATA)
{source table,#ARRAY{0,#ARRAY{couleur,vert},1,#ARRAY{couleur,bleu}}}
{"<br>"}
>
[(#VALEUR{couleur})] est équivalent à [(#COULEUR)]
</BOUCLE_couleurs>
Résultat :
vert est équivalent à vert
bleu est équivalent à bleu
À noter : quand #VALEUR
est un tableau, on peut accéder à #VALEUR{ma_cle}
qui est équivalent à #MA_CLE
Lister les plugins
actifs
Le format de source plugins
ne nécessite pas de jeu de données en entrée.
Boucle :
<BOUCLE_pl(DATA){source plugins}>
#VALEUR
</BOUCLE_pl>
Résultat :
crayons memoization icalendar
Filtrer les données avec {cle==...}
Itérons sur la balise #CONFIG
qui comporte tous les éléments de configuration du site enregistrés dans la table spip_meta
.
Comme la balise #CONFIG
est un tableau de données, on va employer le format table
. Un critère {cle==version}
filtre le tableau en ne retenant que les valeurs de configuration dont la clé contient le mot « version ».
Boucle :
<BOUCLE_cfg(DATA){source table, #CONFIG*}{cle==version}>
<dt>#CLE</dt>
<dd>#VALEUR</dd>
</BOUCLE_cfg>
Résultat :
...
- version_installee
- 16428
- revisions_base_version
- 1.1
- Indexation_base_version
- 0.4
Lister le contenu d’un répertoire
La fonction glob()
de PHP permet de lister les fichiers correspondant à un masque ; elle a été transposée pour la boucle (DATA)
.
Boucle qui liste par ordre alphabétique les sous-répertoires de IMG
:
<BOUCLE_repertoires(DATA){source ls, #CHEMIN{IMG}/*/}{par basename}>
[(#VAL{Y-m-d H:i:s}|date{#MTIME})] - [(#FILE)] - [(#FILENAME)]<br>
</BOUCLE_repertoires>
Résultat :
2018-02-28 17:33:25 - IMG/gif 2018-02-28 18:44:14 - IMG/jpg 2018-02-28 17:33:20 - IMG/png
Boucle qui liste par date inverse les 3 fichiers les plus récents de IMG/jpg
:
<BOUCLE_fichiers(DATA){source ls, #CHEMIN{IMG}/jpg/*.jpg}
{!par mtime}
{0,3}
>
[(#VAL{Y-m-d H:i:s}|date{#MTIME})] - [(#FILE)] <br>
</BOUCLE_fichiers>
Résultat :
2018-02-28 18:45:39 - IMG/jpg/IMG011.jpg 2018-02-23 12:22:15 - IMG/jpg/IMG003.jpg 2018-02-23 12:21:47 - IMG/jpg/IMG004.jpg
Lister des fichiers correspondant à un masque
La fonction preg_files
de SPIP permet de lister des fichiers selon une expression régulière et de manière arborescente. [2]
Exemple : les fichiers plugin.xml
du site.
Boucle :
<BOUCLE_xml(DATA){source pregfiles, #EVAL{_DIR_RACINE}, plugin.xml$, 5}>
#VALEUR[ - (#VAL{Y-m-d H:i:s}|date{#VALEUR|filemtime})]
</BOUCLE_xml>
Résultat :
../plugins/a2a/plugin.xml - 2011-04-16 20:47:02 ../extensions/simplog/plugin.xml - 2010-09-05 16:08:39 ../extensions/vertebres/plugin.xml - 2011-03-19 16:49:51 ../extensions/z-core/plugin.xml - 2010-09-05 16:08:47
Lire un fichier CSV
Nous allons cette fois afficher un fichier au format CSV se trouvant sur notre disque dur. Le fichier adresses.csv
contient un carnet d’adresses :
Fil,Philippe,fil@rezo.net,http://rezo.net/
Marcimat,Matthieu,marcimat@rezo.net,http://marcimat.magraine.net/
Boucle :
<BOUCLE_csv(DATA){source csv, adresses.csv}
{par /3}
{"<br>"}>
#VALEUR{0} : #VALEUR{3}
</BOUCLE_csv>
Résultat :
Marcimat: http://marcimat.magraine.net/
Fil: http://rezo.net/
À noter : le critère de tri {par /3}
permet de trier sur la colonne n° 3, contenant les adresses web. Le /
initial est obligatoire dans le cas d’un tri sur une clé numérique ou commençant par un chiffre.
Dans la démo de CSV livrée avec le plugin itérateurs, on trouvera un exemple beaucoup plus complet permettant de gérer proprement les clés du fichier CSV, et même de trier ou de fusionner sur ces clés.
Un document Google (spreadsheet)
Dans Google Documents il est possible de « Partager > Publier un document ». Une fois cela fait, on peut récupérer l’adresse du document au format CSV, et l’afficher sous forme de table HTML.
Boucle :
#SET{key,0AolUP3c6K9JodGwxRjJzb2hyTGZLU29qRVItRXk1VXc}
<B_csv>
<table border="1">
<BOUCLE_csv(DATA){source csv, https://spreadsheets.google.com/pub?key=#GET{key}&hl=en&dsds&output=csv}
>
<tr>
<td>#VALEUR{0}</td>
<td>#VALEUR{1}</td>
<td>#VALEUR{2}</td>
</tr>
</BOUCLE_csv>
</table>
</B_csv>
Résultat :
Pays PIB Population Rémitanie 12 1 Baldoghistan 23 2 Républiques Unies 43 3 Diloduristan 12 4 Zarlatie 9 5
D’autres modes d’extraction sont possibles, notamment sous forme de liste, ou de cellules :
Liste :
Rémitanie pib: 12, population: 1 Baldoghistan pib: 23, population: 2...Cellules :
A2: Rémitanie B2: 12 C2: 1 A3: Baldoghistan B3: 23 C3: 2...
Une page HTML
Lire une page HTML, isoler une ligne avec un certain marquage et y sélectionner une valeur interressante pour l’afficher proprement ? C’est possible ! Ici nous allons afficher le nombre de followers sur un compte twitter.
Boucle :
#SET{followers,'data-nav="followers"'}
<BOUCLE_followers(DATA){source file, https://twitter.com/spip}{valeur == #GET{followers}}>
[<span title="[(#VALEUR|match{title="(.*)",1}|strtolower)]">(#VALEUR|match{title="(.*)",1}|replace{ abonnés}|trim|replace{ \d+$, k})</span>]
</BOUCLE_followers>
Résultat :
1 k
Un webservice au format YAML
Le site http://per.sonn.es/ propose une API permettant de lire chaque profil au format YAML. On va donc interroger le site sur l’un de ces profils, et parcourir le résultat pour afficher la liste des amis de la personne concernée.
Commençons par analyser mon profil (à l’adresse http://per.sonn.es/Fil.yaml) :
name: Fil
sex: F
birthday: '1966-08-17'
job: Calorifugeur
friends:
- 'Maude Guérin'
- 'Zohra Robin'
- 'Pierre-Yves Philippe'
- 'Lauriane Bertin'
- 'Jeannine Pichon'
- 'Vanessa Michel'
- 'Wendy Allard'
...
city: 'Mouxy (Rhone-Alpes)'
Si l’on charge cette adresse avec le format yaml
, on obtient un tableau de données un peu plus complexe que dans l’exemple précédent. En effet, certains items sont des chaînes de caractères, d’autres, comme la liste d’amis, des listes de chaînes.
(name => Fil, sex => F, friends => ( Maude Guérin, Zohra Robin, ...), ... )
.
Parcourons ces données :
Boucle :
<BOUCLE_yaml(DATA){source yaml, http://per.sonn.es/Fil.yaml}>
<dt>#CLE</dt>
<dd>[(#VALEUR|print)]</dd>
</BOUCLE_yaml>
Résultat :
...
- name
- Fil
- sex
- F
- birthday
- 1966-08-17
- job
- Calorifugeur
- friends
- Maude Guérin, Zohra Robin, Pierre-Yves Philippe, Lauriane Bertin, Jeannine Pichon, Vanessa Michel, Wendy Allard, Sylvie Michaud, Gwenaël Voisin, Paule Mary, Maia Ribeiro, Josianne François, Lucas Fernandes
Maintenant, nous voulons boucler sur les amis de Fil. Pour cela il y a deux possibilités. La première consiste à récupérer les données avec notre boucle (DATA)
au format yaml
, puis à stocker le tableau d’amis dans une variable que nous allons parcourir avec une autre boucle (DATA)
, cette fois au format table
:
Boucle :
<BOUCLE_yaml2(DATA){source yaml, http://per.sonn.es/Fil.yaml}{cle=friends}>
<BOUCLE_friends(DATA){source table, #VALEUR}{" - "}>
#VALEUR
</BOUCLE_friends>
</BOUCLE_yaml2>
Résultat :
Maude Guérin - Zohra Robin - Pierre-Yves Philippe - Lauriane Bertin - Jeannine Pichon - Vanessa Michel - Wendy Allard - Sylvie Michaud - Gwenaël Voisin - Paule Mary - Maia Ribeiro
Le critère {datapath ...}
On voit bien dans l’exemple ci-dessus que, plus le tableau de données est complexe, plus les boucles qu’il va falloir imbriquer seront pénibles à coder. C’est là qu’intervient le critère {datapath ...}
, qui permet d’indiquer à la boucle (DATA)
le chemin (au sens de Xpath) vers le tableau de données qui nous intéresse [3].
Avec cette balise notre liste d’amis s’écrit en une seule boucle (et on en profite pour ajouter une pagination) :
Boucle :
<BOUCLE_yaml3(DATA)
{source yaml, http://per.sonn.es/Fil.yaml}
{datapath friends}
{" - "}{pagination 10}
>
#VALEUR
</BOUCLE_yaml3>
#PAGINATION
</B_yaml3>
Résultat :
Maude Guérin - Zohra Robin - Pierre-Yves Philippe - Lauriane Bertin - Jeannine Pichon - Vanessa Michel - Wendy Allard - Sylvie Michaud - Gwenaël Voisin - Paule Mary
0 | 10 | 20 | 30 | 40 | ...
Une API en json
Pour afficher des images d’écureuils issues d’Instagram (du temps où instagram proposait une API json, mais cette fonctionnalité a été retirée) :
<BOUCLE_instagram(DATA)
{source json, https://www.instagram.com/explore/tags/squirrel/?__a=1}
{datapath graphql/hashtag/edge_hashtag_to_media/edges}
>
<BOUCLE_images(DATA){source table,#VALEUR}{!par taken_at_timestamp}>
<a href="#DISPLAY_URL">[(#THUMBNAIL_SRC|balise_img)]</a>
</BOUCLE_images>
</BOUCLE_instagram>
Résultat :
Un fichier XML
Le plugin « citations aléatoires » sur SPIP-Zone contient un fichier de citations, au format XML (http://zone.spip.org/trac/spip-zone/browser/_plugins_/citation_aleatoire/trunk/citations/citations_fr.xml). La boucle (DATA)
permet de l’exploiter directement :
Boucle :
[(#REM) Récupérer le fichier au format txt de la zone - mieux vaut l'enregistrer localement sur le serveur]
[(#SET{c,http://zone.spip.org/trac/spip-zone/browser/_plugins_/citation_aleatoire/trunk/citations/citations_fr.xml?format=txt})]
<dl>
<BOUCLE_cite(DATA)
{source xml, #GET{c}}
{par hasard}{0,1}
>
[<dt>(#VALEUR{0/auteur/0})</dt>]
[<dd>(#VALEUR{0/texte/0})</dd>]
</BOUCLE_cite>
</dl>
Résultat (au hasard donc) :
- L'idéal quand on veut être admiré, c'est d'être mort.
- (Michel Audiard)
Utiliser un webservice comme YQL — Yahoo Query Language)
YQL est un webservice permettant d’interroger de façon simple de nombreux sites comme google, twitter, flickr, etc. Avec la boucle (DATA)
, SPIP facilite grandement son intégration sous forme de boucles : Cf. http://zzz.rezo.net/Exemples-de-bou....
Les Itérateurs PHP
SPIP est capable d’utiliser les itérateurs PHP standards. Il convient de se reporter à leur documentation, qui est souvent très succincte, et de vérifier que les itérateurs en questions sont disponibles sur votre système.
Notons, par exemple, DirectoryIterator
, qui permet de lister les fichiers d’un répertoire :
Boucle :
<pre>
<BOUCLE_ls(php:DirectoryIterator){args IMG/jpg/}
{pagination 10}
{valeur!==^\.}{valeur==\.jpg$}
>[(#VAL{Y-m-d H:i:s}|date{#GETMTIME})] / #VALEUR
</BOUCLE_ls>
</pre>
#PAGINATION
</B_ls>
Résultat :
2008-02-01 23:27:23 / arton2135.jpg 2008-08-21 11:12:58 / DSC03420.jpg 2008-08-21 11:13:11 / DSC03421.jpg 2009-08-27 11:20:11 / hash-1.jpg 2009-08-27 11:20:04 / hash.jpg
Il convient d’indiquer à SPIP qu’il s’agit d’un itérateur PHP, en indiquant (php:...)
avant le nom de l’itérateur.
Le critère {args xx,yy}
définit les arguments que l’on va passer à l’itérateur lors de son initialisation. Pour DirectoryIterator
, il s’agit du chemin du répertoire à lister.
Les méthodes de cet itérateur (cf. http://php.net/manual/fr/class.directoryiterator.php) sont disponibles sous forme de balises (ici, #GETMTIME
).
Remarque : pour lister le contenu d’un répertoire, le format glob
de la boucle (DATA)
est sans doute plus facile à utiliser que cet itérateur PHP.<BOUCLE_ls(DATA){source ls, IMG/jpg/*.jpg}
{!par mtime}> ...
Un calendrier au format iCalendar/ics
Cette fonctionnalité nécessite l’activation du plugin iCalendar. Il est alors possible d’itérer sur les événements d’un calendrier publié au format iCalendar/ics. L’article consacré sur SPIP-Contrib au plugin icalendar donne un exemple complet.