De syntax van de lus (BOUCLE)

Basis syntax

De vereenvoudigde syntax van een lus (in het Frans: boucle) is de volgende:

<BOUCLEn(TYPE){voorwaarde1}{voorwaarde2}...{voorwaardeX}>
* HTML code + SPIP bakens
</BOUCLEn>

In de uitleg over lussen en bakens hebben we gezien dat «HTML code + SPIP bakens» zich steeds herhaalt wanneer de lus in de database gegevens vindt die aan alle voorwaarden voldoen (nooit, één keer of meerdere keren).

De belagrijke regel hier is:

<BOUCLEn(TYPE){voorwaarde1}{voorwaarde2}...{voorwaardeX}>

-  Het element BOUCLE geeft aan dat het om een lus van SPIP gaat. Deze mag hem dus niet veranderen, of in andere woorden: alle lussen in SPIP beginnen met de opdracht BOUCLE.

-  Het element n is de naam of het nummer van de lus, wat de webmaster zelf mag verzinnen voor iedere lus die hij schrijft (let op: de naam mag uitsluitend bestaan uit alfanumerieke tekens zonder accenten in kleine letters en «het liggende streepje (underscore)»; dat wil dus zeggen tekens van de klasse [a-zA-Z0-9_]. We wullen later zien dat in hetzelfde skelet meerdere lussen kunnen worden gebruikt: hun naam is dus van belang om ze te kunnen identificeren.

Wanneer je ervoor kiest de lussen te nummeren, wordt de syntax bijvoorbeeld:
<BOUCLE5...> ... </BOUCLE5>

Als je voor de (meer praktische) oplossing kiest ze een naam te geven (en je je skelet dus beter "leesbaar" maakt), moet je deze naam vooraf laten gaan door een «_» (underscore). Bijvoorbeeld:
<BOUCLE_subrubrieken...> ... </BOUCLE_subrubrieken>

-  Het element (TYPE) is essentieel: het geeft aan wat voor element je wilt ophalen. De syntax is belangrijk: het TYPE wordt in hoofdletters tussen ronde haakjes aangegeven (zonder spaties) en het moet natuurlijk overeenkomen met één van de in SPIP gedefinieerde types (die je in deze documentatie terugvindt): ARTICLES, RUBRIQUES, AUTEURS, enz.

Voor het bovengaande voorbeeld wordt het dus:

<BOUCLE_subrubrieken(RUBRIQUES)...>
...
</BOUCLE_subrubrieken>

Bij het afsluiten van de lus, hoeft het TYPE dus niet te worden herhaald.

-  De voorwaarden (criteria) {voorwaarde1}{voorwaarde2}...{voorwaardeX} geven ieder aan waaraan de gegevens die we in de database opzoeken moeten voldoen (toon de subrubrieken van deze rubriek, toon de andere rubrieken op hetzelfde niveau als deze rubriek, ...), en de manier waarop we die elementen willen klasseren of selecteren (klasseren op datum, naar titel... alleen de eerste 3 elementen weergeven, de helft weergeven...). Omdat de voorwaarden kunnen worden gecombineerd, kunnen krachtige opvragingen worden uitgevoerd, zoals «toon de 5 meest recente artikelen geschreven door deze auteur».

De voorwaarden staan tussen accolades en voor een betere leesbaarheid mag je een onderlinge spatie aanbrengen. Bijvoorbeeld (zie hierboven):

<BOUCLE_zelfde_auteur(ARTICLES) {id_auteur} {par date}{inverse} {0,5}>
...
</BOUCLE_zelfde_auteur>

De verschillende voorwaarden en hun syntax worden verderop uitgelegd, voor ieder type lus (sommige voorwaarden zijn op alle lussen toepasbaar, andere zijn specifiek voor één of meer bepaalde lussen).

Volledige syntax

We kunnen de hierboven omschreven syntax vervolledigen met aanvullende elementen. Feitelijk kan de voorafgaande lus uitsluitend de bakens (de inhoud van het TYPE) binnen de lus zelf weergeven. Maar met SPIP kan ook worden aangegeven wat vóór of ná die lus moet worden weergegeven wanneer één of meer resultaten gevonden worden en wat moet worden weergegeven wanneer niets wordt gevonden.

We krijgen dan:
<Bn>
* Optionele code vooraf
<BOUCLEn(TYPE){voorwaarde1}{voorwaarde2}...{voorwaardeX}>
* HTML code + SPIP bakens
</BOUCLEn>
* Optionele code achteraf
</Bn>
* Alternatieve code
<//Bn>

De optionele code vooraf (die woord voorafgegaan door <Bn>) wordt uitsluitend weergegeven wanneer de lus tenminste één resultaat geeft. De code wordt dus weergegeven boven de resultaten van de lus.

Let op :
Hoewel ze boven de inhoud van de lus wordt geplaatst, wordt ze pas berekend nadat de lus werd uitgevoerd (hoe zou SPIP anders kunnen weten of de code moet worden geplaatst). Maar het maakt ook het baken #TOTAL_BOUCLE mogelijk, wat het aantal elementen in het resultaat aangeeft.

De optionele code achteraf (gevolgd door </Bn>) wordt ook alleen uitgevoerd wanneer de lus tenminste één resultaat geeft. De code wordt onder de resultaten van de lus weergegeven.

De alternatieve code (gevolgd door <//Bn>) wordt in plaats van de lus (en dus ook in plaats van de code vooraf en achteraf) weergegeven wanneer de lus geen resultaat geeft, ofwel omdat de database geen enkel element bevat dat aan de voorwaarden voldoent, ofwel omdat de code die in de lussen wordt gebruikt niets weergeeft.

Kijk bijvoorbeeld naar deze code:

<B1>
  Deze rubriek bevat de volgende elementen:
  <ul>
    <BOUCLE1(ARTICLES){id_rubrique}>
    <li>#TITRE</li>
    </BOUCLE1>
  </ul>
</B1>
  Deze rubriek bevat geen artikelen.
<//B1>

geeft het volgende resultaat:

-  wanneer er één artikel gevonden wordt:

Deze rubriek bevat de volgende elementen:
 <ul>
   <li>Titel van het artikel</li>
</ul>

-  wanneer er meerdere artikelen gevonden worden:

Deze rubriek bevat de volgende elementen:
 <ul>
   <li>Titel van artikel 1</li>
   <li>Titel van artikel 2</li>
   ...
   <li>Titel van het laatste artikel</li>
</ul>

-  wanneer niets gevonden wordt:

Deze rubriek bevat geen artikelen.

Terug in de tijd: Tot [SPIP 1.7.2] verbood de manier waarop SPIP de lussen interpreteerde om een lus binnen <Bn> en <BOUCLEn> te plaatsen. Wel konden aanvullende lussen na de definitie <BOUCLEn...> worden opgenomen. Wanneer je daadwerkelijk een lus wilt plaatsen in het gedeelte vooraf moet je dat doen door middel van opdracht <INCLURE{}>.

.

Verkorte syntax

Sinds SPIP 2.0 is het in bepaalde gevallen mogelijk een vereenvoudigde schrijfwijze voor lussen toe te passen.

Om bijvoorbeeld uitsluitend het aantal resultaten van een lus op te vragen (met het baken #TOTAL_BOUCLE) mag je schrijven:

<BOUCLE_a(ARTICLES) />#TOTAL_BOUCLE<//B_a>

in plaats van:

<BOUCLE_a(ARTICLES) > </BOUCLE_a>#TOTAL_BOUCLE</B_a>

Deze vereenvoudigde schrijfwijze kan ook nuttig zijn als je alleen een lijst van «doublons» wilt maken. Het toevoegen van deze voorwaarde zorgt ervoor dat een bepaald element slecht éénmaal wordt weergegeven:

<BOUCLE_a(ARTICLES) {critères ...} {doublons}/>

Trapsgewijze omgevingsvoorwaarden

Iedere lus voert een selectie uit aan de hand van de vermelde voorwaarden. Daarbij worden sommige voorwaarden bepaald door de "omgeving" waarin de lus zich bevindt.

Bijvoorbeeld: als je een lus maakt in de trend «Toon de artikelen in deze rubriek», moet SPIP weten over welke rubriek je het hebt. Dat is wat we bedoelen met de "omgeving" of de "context".

-  De door de URL geleverde context

Wanneer je een pagina van een SPIP site bezoekt, bevat het adres (de URL) in het algemeen een variabele. Bijvoorbeeld: spip.php?rubrique15.

Deze variabele levert dus een eerste context: de lus «Toon de artikelen in deze rubriek» gaat dat dus interpreteren als «Toon de artikelen in rubriek 15».

-  De context die door andere lussen wordt geleverd

Binnen een lus wordt de context aangepast door ieder element van de lus. Door lussen binnen elkaar te plaatsen, kun de context dus worden geërfd van de buitenliggende lus.

We kijken naar de volgende structuur:

<BOUCLE_artikelen: Toon de artikelen in deze rubriek>
  Toon de titel van het artikel
  <BOUCLE_auteurs: Toon de auteur(s) van dit artikel>
    Naam van de auteur(s)
  </BOUCLE_auteurs>
</BOUCLE_artikelen>

Je zult begrijpen dat:
-  de eerste lus (BOUCLE_artikelen) de artikelen toont in functie van de rubriek, afkomstig uit de URL (bijvoorbeeld id_rubrique=15);
-  deze lus heeft één of meerdere resultaten (artikelen);
-  «binnen» ieder artikel onstaat een andere context (die van het artikel, dus bijvoorbeeld id_article=199, maar ook die van de auteur);
-  de tweede lus (BOUCLE_auteurs), die zich binnen de eerste lus bevindt, hangt van elk van zijn successievelijke uitvoeringen (ze wordt uitgevoerd voor ieder resultaat van de eerste lus): «Toon de auteur(s) van dit artikel» wordt dus achtereenvolgens «toon de auteurs van het eerste artikel», «van het tweede artikel», enzovoort.

Je iet dat je door trapsgewijs lussen op te bouwen, je een structuur van lussen krijgt die van elkaar afhankleijk zijn. De buitenste lus hangt af van de parameter(s) waarmee hij opgeroepen werd.

Ingesloten en opeenvolgende lussen

Als je al lussen binnen elkaar mag opnemen, dan mag je zeker lussen na elkaar plaatsen: lussen die elkaar niet beïnvloeden.

Zo is de webpagina van een rubriek typisch uit de volgende elementen opgebouwd (waarbij ook weer met een vereenvoudigde schrijfwijze is toegepast):

<BOUCLE_rubriek(RUBRIQUES){id_rubrique}>
  <ul>Titel van de rubriek
  <BOUCLE_artikelen(ARTICLES){id_rubrique}>
    <li> Titel van het artikel</li>
  </BOUCLE_artikelen>
  <BOUCLE_subrubrieken(RUBRIQUES){id_rubrique}>
    <li> Titel van de subrubriek </li>
  </BOUCLE_subrubrieken>
  </ul>
</BOUCLE_rubriek>
  <p>Deze rubriek bestaat niet.</p>
<//B_rubriek>

De eerste lus (BOUCLE_rubriek) is afhankelijk van de variabele waarmee hij werd opgeroepen (bijvoorbeeld id_rubrique=15).

De volgende lussen (BOUCLE_artikelen en BOUCLE_subrubrieken) zijn binnen de eerste lus geplaatst. Dus als rubriek 15 niet zou bestaan, zou de eerste lus geen resultaat geven (en wordt «Deze rubriek bestaat niet.» afgebeeld) en worden de twee volgende lussen volledig genegeerd. Maar bestaat rubriek 15 wel, dan zullen de twee andere lussen worden geanalyseerd.

We zien ook dat deze twee lussen na elkaar staan. Zo werken zijn in functie van de eerste lus, maar onafhankelijk van elkaar. Staat er geen artikel in rubriek 15 (BOUCLE_artikelen), dan wordt toch de lijst van subrubrieken van rubriek 15 (BOUCLE_subrubrieken) weergegeven, en omgekeerd.

Tellers

Twee bakens maken het tellen van de resultaten van een lus mogelijk.


-  #TOTAL_BOUCLE geeft het totaal aantal resultaten van de lus weer. We kunnen het baken in de lus gebruiken, binnen het optionele deel van de lus — «vooraf» en «achteraf» — of zelfs in het alternatieve deel «na» de lus.
Om bijvoorbeeld het aantal documenten dat gekoppeld is aan een artikel weer te geven:

<BOUCLE_art(ARTICLES){id_article}>
  <BOUCLE_doc(DOCUMENTS) {id_article}></BOUCLE_doc>
    [ (#TOTAL_BOUCLE) document(en) gevonden.]
  <//B_doc>
</BOUCLE_art>

Let op: wanneer het middendeel van een lus niets retourneert (dat is het geval met de lus <BOUCLE_doc> hierboven, die uitsluitend dient om het aantal resultaten te tellen), kan #TOTAL_BOUCLE uitsluitend worden weergegeven in het alternative deel «na» de lus vóór (<//B_doc>).


-  #COMPTEUR_BOUCLE geeft een telling in de lus weer en toont de actuele waarde. Je kunt deze dus gebruiken om de resultaten te nummeren:

<BOUCLE_art(ARTICLES) {par date} {inverse} {0,10}>
#COMPTEUR_BOUCLE - #TITRE<br>
</BOUCLE_art>

Auteur Hanjo Gepubliceerd op: Aangepast: 21/03/23

Vertalingen: عربي, català, Deutsch, English, Español, français, italiano, Nederlands, русский, українська