Sintaxe básica
A sintaxe simplificada de um loop é a seguinte:
<BOUCLEn(TIPO){critério1}{critério2}{...}{critériox}>
* Código HTML + tags SPIP
<BOUCLEn>
Vimos, na explicação sobre os loops e as tags, que o «Código HTML + tags SPIP » repetem-se tantas vezes quanto o loop obtiver elementos tirados da base de dados (ouo seja, uma vez, várias vezes, ou zero vezes).
A linha importante, aqui, é:
<BOUCLEn(TIPO){critério1}{critério2}{...}{critériox}>
- O elemento BOUCLE
é o comando que indica que se trata de um loop SPIP; não pode ser modificado, ou seja, todos os lopps do SPIP começam com a instrução BOUCLE
.
- O elemento n é o nome ou o número do loop, escolhido livremente pelo webmaster para cada loop utilizada por ele (atenção: deve-se ter cuidado para nomear os loops unicamente com caracteres alfanumérios não acentuados e o sublinhado «underscore»; ou seja, os carateres da classe [a-zA-Z0-9_]. Mais à frente veremos que é possível (é mesmo de todo interessante) utilizar vários loops num mesmo template: nomeá-los é portanto indispensável para identificá-los.
Se decidir numerar os seus loops, a sintaxe passa a ser, por exemplo (para o loop-5):
<BOUCLE5...> ... </BOUCLE5>
Se decidir nomear os seus loops (é geralmente mais prático, o seu código fica mais legível), é obrigatório preceder o nome pelo símbolo «_» (que é chamado habitualmente de underscore). Por exemplo:
<BOUCLE_subsecoes...> ... </BOUCLE_subsecoes>
- O elemento (TIPO)
é fundamental: ele indica que tipo de elementos quer recuperar. A sintaxeé importante: o TIPO é indicado entre parêntesis (sem espaços), em maiúsculas, e esse TIPO deve sorresponder obrigatoriamente a um dos tipos previstos no SPIP (que podem ser encontrados na presente documentação): ARTICLES, RUBRIQUES, AUTEURS, BREVES etc.
Para o exemplo precedente, teremos então:
<BOUCLE_subsecoes(RUBRIQUES){...}>
...
</BOUCLE_subsecoes>
- Os critérios {critério1}{critério2}...{critériox}
indicam por quais critérios queremos selecionar os elementos da base de dados (exibir a subseções desta seção, exibir as outras seções que existam no mesmo nível hierárquico desta seção...) e de que maneira iremos classificar ou selecionar os elementos (classificar as matérias de acordo com as suas datas, os seus títulos... exibir únicamente as 3 primeiras matérias, exibir a metade das matérias...). Como se pode combinar os critérios, pode-se muito facilmente criar consultas muito poderosass, do tipo «exibir a lista das 5 matérias mais recentes escritas por este autor».
Os critérios ficam entre chavetas e podem ser separados uns dos outros por um espaço.
Exemplo:
<BOUCLE_mesmo_autor(ARTICLES){id_auteur}{par date}{inverse}{0,5}>
...
</BOUCLE_mesmo_autor>
Os diferente critérios e sua sintaxe serão detalhados em seguida, para cada tipo de loop (alguns critérios funcionam para todos os tipos de loops, outros são específicos de certos loops).
Sintaxe completa
A sintaxe apresentada anteriormente pode ser completada por elementos condicionais ou [após o SPIP 4.0] por elementos incondicionais porém associados aos retornos do loop.
Elementos condicionais: o loop apresentado acima exibe sucessivamente os elementos contidos no interior do loop. O SPIP permite também determinar o que deve ser exibido antes e depois do loop, caso ele contenha um ou mais resultados, e o que deve ser exibido se não houver nenhum elemento.
Isso dá:
<BBn>
* Código opcional não condicional anterior
<Bn>
* Código opcional anterior
<BOUCLEn(TIPO){critério1}{critério2}{...}{critériox}>
* Código + tags SPIP
</BOUCLEn>
* Código opcional posterior
</Bn>
* Código alternativo
<//Bn>
* Código opcional não condicional posterior
<//BBn>
O código opcional «anterior» (precedido de <Bn>
) só será exibido se o loop contiver pelo menos uma resposta. Ele é exibido antes dos resultados do loop.
Atenção:
Apesar de ser exibido antes do corpo principal do loop, o código opcional «anterior» é calculado após a execução do loop (o que permite, por exemplo, exibir a tag#TOTAL_BOUCLE
antes da exibição dos retornos particulares do loop).
O código opcional «posterior» (terminado por </Bn>
) só será exibido se o loop contiver pelo menos uma resposta. Ele é exibido após os resultados do loop.
O código alternativo (terminado por <//Bn>
) é exibido no lugar do loop (e portanto igualmente no lugar dos códigos opcionais anterior e posterior) se o loop não exibir nada seja porque a base de dados não forneceu nenhuma resposta, seja porque o código que utiliza essas respostas no loop não exibam nada.
Por exemplo, o código:
<B1>
Esta seção contém os elementos abaixo:
<ul>
<BOUCLE1(ARTICLES){id_rubrique}>
<li>#TITRE</li>
</BOUCLE1>
</ul>
</B1>
Esta seção não contém nenhuma matéria.
<//B1>
gera os seguintes resultados:
- se houver uma única matéria:
Esta seção contém os elementos abaixo:: <ul> <li>Título da matéria</li> </ul>
- se houver várias matérias:
Esta seção contém os elementos abaixo:: <ul> <li>Título da matéria 1</li> <li>Título da matéria 2</li> ... <li>Título da última matéria</li> </ul>
- se não houver nenhuma matéria:
Esta seção não contém nenhuma matéria.
Elementos incondicionais mas associados ao loop
O SPIP 4.0 introduziu a possibilidade de especificar partes incondicionais antes e após cada loop, no interior dos quais pode-se interrogar as tags relativas à execução do loop, haja ou não um resultado.
Para isso, deve-se usar <BB>
e </BB>
, como no exemplo a seguir:
<BB_meuloop>
<div class="style_meuloop">
<h1>Há [(#TOTAL_BOUCLE) ]matérias</h1>
<B_meuloop>
<ul>
<BOUCLE_meuloop(ARTICLES){id_article?}{0,5}>
<li>#ID_ARTICLE::#TITRE</li>
</BOUCLE_meuloop>
</ul>
</B>
<p>Talvez tenha cometido um erro?...</p>
<//B>
</div>
</BB>
Particularmente, pode-se usar as tags #PAGINATION, #TRI, #TOTAL_BOUCLE
e #GRAND_TOTAL
, para, por exemplo, construir os cabeçalhos de uma tabela ou de uma lista de resultados.
Tabelas condicionais
Após o SPIP 4.0, é possível escrever um loop sobre uma tabela que pode ou não existir. Isto é útil para, por exemplo, criar uma parte que só será exibida se o plugin que criar essa tabela estiver instalado e ativado. Para evitar um erro se a tabela não existir, inclui-se um ?
após o seu nome.
Por exemplo, o plugin organiseur
(que fazia parte dos plug-in-dist) gera um fluxo RSS que fornece informações relativas aos fóruns pesoais... apenas se a tabela FORUMS existir:
<BOUCLE_RSS2(FORUMS ?){!par date_heure}{!doublons F}{tout}{statut=perso} >
Sintaxe abreviada
É possível em alguns casos usar uma nomenclatura abreviada para os loops.
Assim, para recuperar apenas o número total de retornos da consulta (com a tag #TOTAL_BOUCLE
) pode-se escrever:
<BOUCLE_a(ARTICLES) />#TOTAL_BOUCLE<//B_a>
em vez de:
<BOUCLE_a(ARTICLES) > </BOUCLE_a>#TOTAL_BOUCLE</B_a>
Esta nomenclatura abreviada pode ser útil quando se pretende apenas preencher uma tabela de «doublons» :
<BOUCLE_a(ARTICLES) {critères ...} {doublons}/>
Loops anónimos
Após o SPIP 4.0, é igualmente possível criar loops anónimos, ou seja, sem nome, desde que esses loops não estejam aninhados. Umvasto número de loops simples, completos ou parciais, estão envolvidos.
A sintaxe é a mesma exceto qe não existe o número ou o nome n do loop.
Exemplo:
<BB>
<div style="border:5px solid red;padding:20px;">
<h1>[(#TOTAL_BOUCLE) ]matérias</h1>
<B>
<ul>
<BOUCLE(ARTICLES){id_article?}{0,5}>
<li>#ID_ARTICLE::#TITRE</li>
</BOUCLE>
</ul>
</B>
<p>Talvez tenha cometido um erro?...</p>
<//B>
</div>
</BB>
Pode-se evidentemente ter vários loops anónimos numa página, e um mesmo loop anónimo pode estar presente várias vezes na página.
Internamente, e para referenciar este loop na página de depuração (obtida com var_mode=debug
), o compilador gera um identificador único para cada loop anónimo (número de linha do ficheiro de origem + hash).
Os critérios de ambiente em cascata
Cada loop realiza a seleção dos elementos extraídos da base de dados em função de critérios. Alguns desses critérios correspondem ao ambiente no qual o loop se encontra.
Por exemplo: se planeamos um loop do género «Exibir as matérias incluídas nesta seção», é necessário saber de qual seção se trata. É a isto que chamamos ambiente.
- O ambiente fornecido pelo URL
Ao visitarmos uma página de um site em SPIP, o seu endereço contém geralmente uma variável. Por exemplo: spip.php?rubrique15
Esta variável define portanto um primeiro ambiente: o loop «Exibir as matérias incluídas nesta seção» deve ser entendida como «Exibir as matérias da seção 15».
Obviamente, com o mesmo código de template, se chamarmos o endereço: spip.php?rubrique7
; a interpretação deste loop será «Exibir as matérias da seção 7».
- O ambiente fornecido pelos outros loops
No interior de um loop, o ambiente é alterado por cada elemento do loop. Ao colocar loops uns dentro dos outros, herdamos ambientes aninhados uns dentro dos outros.
Assim, na estrutura a seguir:
<BOUCLE_materias: exibir as matérias desta seção>
Exibir o título da matéria
<BOUCLE_autores: exibir os autores desta matéria
Nome do autor
</BOUCLE_autores>
</BOUCLE_materias>
Deve-se compreender que:
- o primeiro loop (BOUCLE_materias
) exibe as matérias em função da seção, de acordo com o ambiente fornecido pelo URL (id_rubrique=15
por exemplo);
- neste loop, obtém-se uma ou mais matérias;
- «no interior» de cada uma dessas matérias, tem-se um ambiente diferente (o da matéria, ou seja, por exemplo, id_article=199
);
- o segundo loop (BOUCLE_autores
), que se encontra no interior do primeiro loop depende, para cada uma de suas execuções sucessivas (ele é executado para cada matéria do primeiro loop): «exibir os autores desta matéria» torna-se sucessivamente «exibir os autores da primeira matéria», «da segunda matéria» e assim por diante.
Vemos que, ao aninhar loops socessivos, obtém-se loops diferentes, incluídos uns nos outros, que dependem do resultado dos loops nos quais eles estão localizados. E, finalmente, o loop inicial (aquele que contém todos os outros) depende de um parâmetro especificado no endereço da página.
Loops incluídos e loops sucessivos
Se é possível incluir loops uns dentro de outros (cada loop incluído dependendo assim do resultado do loop no interior do qual ele está instalado), pode-se também colocar loops uns em seguida a outros; os loops sucessivos não influem uns nos outros.
Por exemplo. a página de uma seção ´e tipicamente constituída dos elementos a seguir:
<BOUCLE_secao(RUBRIQUES){id_rubrique}>
<ul>Título da seção
<BOUCLE_materias(ARTICLES){id_rubrique}>
<li>Título da matéria</li>
</BOUCLE_materias>
<BOUCLE_subsecoes(RUBRIQUES){id_rubrique}>
<li>Título da subseção</li>
</BOUCLE_subsecao>
</ul>
</BOUCLE_secao>
<ul>Não há nenhuma seção neste endereço.</ul>
<//B_secao>
O primeiro loop (BOUCLE_rubrique
) depende da variável passada no URL da página (id_rubrique=15
por exemplo).
Os loops seguintes (BOUCLE_materias
e BOUCLE_subsecoes
) estão colocados no interior do primeiro loop. Assim, se não existir a seção 15, o primeiro loop não terá nenhum resultado (o código alternativo «Não há nenhuma seção...» é exibido), é portanto os dois loops internos são totalmente ignorados. Mas se existir uma seção 15, estes dois loops serão analisados.
Constata-se igualmente que estes dois loops apresentam-se um após o outro. Ambos funcionam em função do primeiro loop, mas independentemente um do outro. Se não houver matérias na seção 15 (BOUCLE_materias
), mesmo assim será exibida a lista de subseções da seção 15 (BOUCLE_sous_rubriques
); e vice-versa.
Contadores
Duas tags permitem contar os resultados dos loops.
- #TOTAL_BOUCLE retorna o número total de resultados obtidos pelo loop. Pode ser usado dentro do loop, nas suas partes opcionais — «anterior» e «posterior» — ou mesmo na parte alternativa «após» o loop.
Por exemplo, para exibir o número de documentos associados a uma matéria:
<BOUCLE_mat(ARTICLES){id_article}>
<BOUCLE_doc(DOCUMENTS) {id_article}></BOUCLE_doc>
[Há (#TOTAL_BOUCLE) documento(s).]
<//B_doc>
</BOUCLE_mat>
Atenção: se a parte central do loop não retornar nada (é o caso do loop
<BOUCLE_doc>
acima, que serve apenas para contar o número de resultados),#TOTAL_BOUCLE
só poderá ser exibido na parte alternativa «após» o loop (<//B_doc>
).
- #COMPTEUR_BOUCLE retorna o número da iteração corrente do loop. Pode-se, por exemplo, usá-lo para numerar os resultados:
<BOUCLE_mat(ARTICLES) {par date} {inverse} {0,10}>
#COMPTEUR_BOUCLE - #TITRE<br>
</BOUCLE_mat>