Exemples de `BOUCLE(DATA)`

Quelques exemples de boucles (DATA) permises par les itérateurs de SPIP.

  • Apparu en : SPIP 3.0

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 :

<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.

Notes

[1Voir : #SET et #GET

[2Plus versatile, mais plus lente que glob.

[3Pour vous aider à déterminer le datapath, vous pouvez visualiser le tableau des résultats en insérant le code [<pre>(#VALEUR|print_r{1})</pre>] dans votre boucle data/

Auteur Fil Publié le : Mis à jour : 23/07/23

Traductions : English, français, Nederlands