how to extend the capabilities of your loops

Here are given several techniques to extend the possibilities offered by SPIP standard loops :

First a technique to test the IN criterium of a loop with SPIP 1.9.2 or 2.0.x and also offering the possibility to write loops that seemed impossible to do.

Then a second technique available for SPIP 2.0.x, to make new loops with « automatic » or « forced » joins.

Ask for the moon to your loops :) !

The idea

Let’s say you often use the same list of values in the IN criterium of a loop.

example in the following loop :

<BOUCLE_art(ARTICLES){id_article IN 12,13,14,25}>
	<h1>#TITRE</h1>
</BOUCLE_art>

The preceding loop lists items IDs 12, 13, 14 or 25.

A solution for sharing your list in a single skeleton

One option for sharing this list is to load it into a static array (see #ARRAYS on the use of arrays). We can then use it several times in the same skeleton (which makes it easier to maintain), for example :

[(#SET{myarray,#ARRAY{0,12,1,13,2,14,3,25}})]

<BOUCLE_art1(ARTICLES){id_article IN #GET{myarray}|sinon{0}}{par hasard}>
	<h1>#TITRE</h1>
</BOUCLE_art1>

<BOUCLE_art2(ARTICLES){id_article IN #GET{myarray}|sinon{0}}{par titre}>
	<h1>#TITRE</h1>
</BOUCLE_art2>

A solution for all the skeletons

Let’s imagine you use that list in several skeletons.

Here’s one way to share the list :

You create a simple skeleton which only contains a string formed from the list of values separated by a rarely-used character (eg the pipe ’|’) :

For example I create the file mylist.html :

12 | 13 | 14 | 25

And the skeleton mytest.html :

#CACHE{0}
<BOUCLE_art(ARTICLES){id_article IN #INCLURE{fond=mylist}|explode{'|'}}>
	<h1>#TITRE</h1>
</BOUCLE_art>

The filter "explode is a php function that separates the string passed as a parameter and fills an array with values. The function takes as first parameter the character used for the separation ... and voila ! It is as if the included skeleton would pass an array parameter.

Application to the achievement of « impossible » loops

Here is an example to make a loop normally impossible with SPIP 1.9.2 : you want to list the articles in the sections marked with the keyword identifier 15.

One possibility offered by dynamic arrays would be to make the following skeleton (see also tools plugin SPIP Bonux to build dynamic arrays) :

#CACHE{0}

#SET{myarray, #ARRAY{}}
<BOUCLE_rub(RUBRIQUES){id_mot=15}>
 [(#SET{myarray,
   #GET{myarray}|push{#ID_RUBRIQUE}
 })]
</BOUCLE_rub>

<BOUCLE_art(ARTICLES){id_rubrique IN #GET{myarray}|sinon{0}}{par titre}>
<h1>#TITRE</h1>
</BOUCLE_art>

This solution works perfectly, but it requires rewriting part of the code in each template where it is used.

Here is a solution where we share the first part :
We create a file list-rubriques.html which creates a list of identifiers separated by pipes.

<BOUCLE_rub(RUBRIQUES){id_mot?}{id_groupe?}{'|'}>#ID_RUBRIQUE</BOUCLE_rub>

You can then use this « sub-loop » in all the other skeletons. For example, it can be used for the following loop in another skeleton :

<BOUCLE_art(ARTICLES){id_rubrique IN #INCLURE{fond=list-rubriques}{id_mot=15}|explode{'|'}|sinon{0}}{par titre}>
<h1>#TITRE</h1>
</BOUCLE_art>

Compatibility :
Tested with SPIP 2.0.9, should also work with SPIP 1.9.2.

A (much) more efficient technique with SPIP 2.0.x

With version 2.0 came « automatic » joins (See Forcing joins on the site programmer.spip.org). We can then use the following loop to get the same result :

<BOUCLE_art(ARTICLES mots_rubriques){id_mot=15}{par titre}>
<h1>#TITRE</h1>
</BOUCLE_art>

The advantage is that :
-  There are no inclusions
-  All the joining work is done by the database, which is much faster.

Here is the request for evidence provided by the debug mode (var_mode=debug) :

SELECT articles.titre, articles.lang
FROM <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+bWFiYXNlPC9jb2RlPg=="></span>.spip_articles
AS <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+YXJ0aWNsZXM8L2NvZGU+"></span>
INNER JOIN <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+bWFiYXNlPC9jb2RlPg=="></span>.spip_mots_rubriques
AS L1 ON ( L1.id_rubrique = articles.id_rubrique )
WHERE (articles.statut = 'publie')
AND (articles.date < '9999-12-31')
AND (L1.id_mot = 15)
GROUP BY articles.id_article
ORDER BY articles.titre
  1. To use the new possibilities offered by SPIP 2.0.x, do not hesitate to use a tool like PhpMyAdmin, proposed in general by all hosters, to discover the tables and their structure (which is very clear !) to find the tables that will intermediate the new joints.
    Then check what sort of joins SPIP does by testing your desired skeleton with the parameter var_mode=debug and displaying the « calculation » generated by the loop in question. For that, you might want to learn some basics of SQL (Structured_Query_Language).
  2. (updated 2010-02-22). One might also read with interest this article dealing with the anti-duplicates. It is a very effective technique for creating groupings of various origins of the same type of object (the UNION in sql). This will prevent in most cases to resort to arrays.

Discussion

Aucune discussion

Ajouter un commentaire

Avant de faire part d’un problème sur un plugin X, merci de lire ce qui suit :

  • Désactiver tous les plugins que vous ne voulez pas tester afin de vous assurer que le bug vient bien du plugin X. Cela vous évitera d’écrire sur le forum d’une contribution qui n’est finalement pas en cause.
  • Cherchez et notez les numéros de version de tout ce qui est en place au moment du test :
    • version de SPIP, en bas de la partie privée
    • version du plugin testé et des éventuels plugins nécessités
    • version de PHP (exec=info en partie privée)
    • version de MySQL / SQLite
  • Si votre problème concerne la partie publique de votre site, donnez une URL où le bug est visible, pour que les gens puissent voir par eux-mêmes.
  • En cas de page blanche, merci d’activer l’affichage des erreurs, et d’indiquer ensuite l’erreur qui apparaît.

Merci d’avance pour les personnes qui vous aideront !

Par ailleurs, n’oubliez pas que les contributeurs et contributrices ont une vie en dehors de SPIP.

Qui êtes-vous ?
[Se connecter]

Pour afficher votre trombine avec votre message, enregistrez-la d’abord sur gravatar.com (gratuit et indolore) et n’oubliez pas d’indiquer votre adresse e-mail ici.

Ajoutez votre commentaire ici

Ce champ accepte les raccourcis SPIP {{gras}} {italique} -*liste [texte->url] <quote> <code> et le code HTML <q> <del> <ins>. Pour créer des paragraphes, laissez simplement des lignes vides.

Ajouter un document

Suivre les commentaires : RSS 2.0 | Atom