Les boucles (DATA) ne portent plus exclusivement sur des requêtes SQL [1], mais elles peuvent tourner sur toutes sortes de listes de données.
Par exemple :
- un tableau de données produit par une fonction quelconque (dont les itérateurs PHP)
- le contenu d’un fichier local au format XML, CSV, JSON, YAML, etc.
- une liste de fichiers dans un répertoire du serveur
- une requête sur un webservice
- une requête SQL (telle que calculée par SPIP, par ex.)
- etc. (LDAP...).
Syntaxe et formats de la boucle (DATA)
C’est une boucle capable d’itérer n’importe quel tableau de données. Sa syntaxe de base est la suivante :
<BOUCLE_exemple(DATA){source format, données}>
#BALISES
</BOUCLE_exemple>
Le critère {source format, données}
définit les données sur lesquelles la boucle va itérer.
La définition d’une source de données nécessite deux éléments :
— La partie données
: cet élément peut être de plusieurs natures :
- un tableau de données, par exemple #ENV*
- le chemin d’un fichier sur le disque dur, ex : sources/definitions.csv
- l’URL d’un fichier ou d’un webservice, ex : http://per.sonn.es/bases/phobia.fr.yaml
- ou encore, une chaîne quelconque que le format saura transformer en tableau de données, ex : "select * from flickr.photos.search where text='spip'"
— La partie format
est à prendre dans la liste ci-dessous :
- table
(alias array
ou tableau
), pour un tableau déjà créé
- csv
, json
, yaml
pour un fichier composé dans l’un de ces formats
- file
pour boucler sur les lignes d’un fichier
- glob
ou pregfiles
pour boucler sur les fichiers d’un répertoire (et plus...)
- rss
(alias atom
) pour lire un flux de nouvelles
- plugins
pour lister les plugins actifs sur le site
- yql
pour envoyer une requête sur le webservice de Yahoo Query Language
- sql
pour envoyer une requête brute au serveur SQL . Attention dans ce cas : 1) la chaîne spécifiant la requête ne doit pas contenir de fins de lignes 2) utiliser la syntaxe {source sql, connecteur:requete}
pour envoyer la requête sur une base externe
- ics
pour boucler sur des calendriers (nécessite le plugin icalendar : lire Plugin iCalendar)
- etc.
Tous ces formats sont déjà disponibles, et il est très aisé d’en ajouter un nouveau, en créant une simple fonction inc_FORMAT_to_array($u)
. A titre d’exemple voici la fonction qui transforme un fichier JSON en tableau de données :
function inc_json_to_array_dist($u) {
if (is_array($json = json_decode($u))
OR is_object($json))
return (array) $json;
}
On peut déclarer une nouvelle boucle DATA dans un fichier inc/ma_source_to_array.php
function inc_ma_source_to_array_dist($data,$param1='',$param2='') {
// $data contient le contenu du fichier (local | distant) ou bien la valeur de la variable passée dans le critère.
// $param1, $param2... sont des paramètres facultatifs
...
}
et l’afficher ensuite :
<BOUCLE_exemple(DATA){source ma_source,test}>
#VALEUR
</BOUCLE_exemple>
Cache :
- Le critère {datacache 3600}
permet de spécifier la durée pendant laquelle le résultat d’une boucle DATA est enregistré en cache. On peut donc désactiver tout cache avec le critère {datacache 0}
- Voir plus d’infos sur les caches des boucles DATA
Filtrage, tri, pagination, fusion
Filtres. Comme les boucles SQL, les boucles (DATA)
peuvent être filtrées par des critères du type {valeur=x}
; les opérateurs disponibles sont =
, >
, <
, >=
, <=
, ==
(expression rationnelle) et LIKE
.
Cependant ce filtrage s’effectue non pas en amont lors de la requête, comme en SQL, mais en aval, sur le tableau de données initialement récupéré.
Tris. Les tris {par xx}
sont également possibles, avec leur variante {!par xx}
pour trier en ordre inverse.
Pagination. La pagination fonctionne normalement, ainsi que le critère {offset,limite}
.
Fusion. Le critère {fusion /x/y}
fonctionne aussi. Par exemple, pour un fichier d’adresses au format CSV, si l’email est le champ n° 3, on pourra ne retenir qu’un seul enregistrement par email avec la boucle suivante :
<BOUCLE_csv(DATA){source csv, adresses.csv}{fusion /3}{par /0}{'<br>'}>
#VALEUR{0} : #VALEUR{3}
</BOUCLE_csv>
La fusion se fait après le tri, et retient le premier élément rencontré. De cette manière, si un tableau est trie {!par date}
puis fusionné sur l’email, l’enregistrement retenu pour chaque email sera le plus récent.
Le critère {liste ...}
Pour simplifier l’écriture de tableaux de données, lorsqu’il s’agit d’une simple liste d’éléments qu’on veut indiquer manuellement, la boucle (DATA)
accepte le critère {liste ...}
, qui permet de constituer un tableau de données en séparant celles-ci par des virgules.
Boucle :
<BOUCLE_i(DATA){liste 3,4,5}{"<br>"}>
<BOUCLE_j(DATA){liste 6,7,8}{" "}>
[(#VALEUR|mult{#_i:VALEUR})]
</BOUCLE_j>
</BOUCLE_i>
Résultat :
18 21 24
24 28 32
30 35 40
A noter : on a utilisé #_i:VALEUR
pour référencer dans la boucle j
la valeur calculée par la boucle i
.
Voir aussi Deux itérateurs simples : les listes et les énumérations
Le critère {enum ...}
<BOUCLE_enumere(DATA){enum 2,10,2}>
#VALEUR
</BOUCLE_enumere>
Résultat :
2 4 6 8 10
<BOUCLE_enum(DATA){enum g,m}{", "}>
#VALEUR
</BOUCLE_enum>
Résultat :
g, h, i, j, k, l, m
val1
et val2
sont 2 valeurs numériques, ou bien 2 caractères. SPIP déterminant laquelle des 2 valeurs est la plus petite, cette boucle va énumérer les valeurs entre val1
et val2
. Dans la première forme, le pas n’est pas précisé : il vaut 1 par défaut.
Voir aussi Deux itérateurs simples : les listes et les énumérations
Protection des données manipulées par les itérateurs
La boucle (DATA)
protège automatiquement toutes les balises qui sont à l’intérieur, car les données qu’on y manipule sont en général de provenance inconnue et potentiellement dangereuse. Cela impacte aussi les balises des formulaires (#FORMULAIRE_xx
) qu’il faut donc utiliser avec un * comme expliqué dans l’article sur les balises étoilées.
<BOUCLE_foreach_protege(DATA){liste a,b,c,d,e}>
#FORMULAIRE_XXX*{#VALEUR}
</BOUCLE_foreach_protege>
A noter : si vous utilisez le plugin "Bonux", il suffira d’utiliser une boucle (POUR)
, qui elle n’a pas ce comportement.
<BOUCLE_Foreach_non_protege(POUR){liste a,b,c,d,e}>
#FORMULAIRE_XXX{#VALEUR}
</BOUCLE_Foreach_protege>
Lire la suite : régalez-vous avec des exemples de boucles (DATA)
!