Advertencia: Arqueología del lenguaje natural
Los términos que utilizan los lenguajes de programación generalmente derivan del inglés
(FOR I==0 TO N DO ...
).
Tal no es el caso de SPIP que fue creado inicialmente en francés. Por eso verás que los términos utilizados derivan del francés: BOUCLE, ARTICLE, RUBRIQUE, MOT, ...
[1]
Se ha discutido la posibilidad de traducir este lenguaje pero claramente las complicaciones que implicaría no valen la pena. Por lo tanto si quieres aprender a hacer un esqueleto SPIP deberás aprender algo más de una decena de palabras de francés. No es la mayor complicación...
La sintaxis básica
La sintaxis simplificada de un bucle es la siguiente:
<BOUCLEn(TYPE){critère1}{critère2}{...}{critèrex}>
* Código HTML + balizas SPIP
<BOUCLEn>
Ya vimos en la explicación de los bucles y las balizas, que el código HTML + las balizas SPIP se repiten tantas veces como elementos se hayan extraído de la base de datos al ejecutar el bucle (es decir una vez, varias veces, o ninguna).
La línea significativa, aquí, es:
<BOUCLEn(TYPE){critère1}{critère2}{...}{critèrex}>
- El elemento BOUCLE
es la orden que indica que se trata de un bucle SPIP; por lo que no se puede modificar; o, dicho de otra manera, que todos los bucles de SPIP comienzan con la instrucción BOUCLE
.
- El elemento n es, a tu elección, el nombre o el número del bucle. A este elemento lo elige la Webmestre, para cada bucle que utilice. Veremos más adelante que es posible (e incluso es lo que interesa en la operación) utilizar varios bucles en el mismo esqueleto: por ende darles un nombre es esencial para identificarlos.
Si decides numerar los bucles, por ejemplo, la sintaxis se convierte (por ejemplo, para el bucle 5):
<BOUCLE5...> ... </BOUCLE5>
Si decides darle un nombre a tus bucles (es generalmente más práctico, el código es más legible), es imprescindible anteponer a este nombre el símbolo "_" (que generalmente se llama underscore). Por ejemplo:
<BOUCLE_subsecciones...>
...
</BOUCLE_subsecciones>
- El Elemento (TYPE)
.
Este elemento es de primera importancia: indica qué tipo de elementos se desea recuperar. La sintaxis es importante: el TYPE se indica entre paréntesis (sin espacios), en mayúsculas, y este TYPE debe corresponder obligatoriamente a uno de los tipos que exista entre los admitidos por SPIP (que encontrarás en la actual documentación): ARTICLES, RUBRIQUES, AUTEURS, BREVES, etc. (ARTÍCULOS, TÍTULOS, AUTORES, BREVES, etc.)
Para el ejemplo precedente, obtenemos:
<BOUCLE_subsecciones(RUBRIQUES)...>
...
</BOUCLE_subsecciones>
- Los criterios {criterio1}{criterio2}
... indican simultáneamente:
- según qué criterios se desea seleccionar los elementos de la base de datos (mostrar las subsecciones incluidas en tal sección, mostrar las otras secciones existentes en el mismo nivel jerárquico que la presente sección...),
- la manera en la cual se clasificarán o seleccionarán los elementos (clasificar los artículos según su fecha, según su título... publicar solamente los tres primeros artículos, mostrar la mitad de los artículos...).
Como los criterios se pueden combinar, es posible generar muy fácilmente peticiones muy potentes a la base de datos, como «mostrar la lista de los 5 artículos más recientes escritos por tal autor»:
<BOUCLE_mismo_autor(ARTICLES){id_auteur}{par date}{inverse}{0,5}>
...
</BOUCLE_mismo_autor>
Los diferentes criterios y su sintaxis serán clarificados a continuación, para cada tipo de bucle (ciertos criterios funcionan con todos los tipos de bucle, otros son específicos para ciertos bucles).
Sintaxis completa
La sintaxis indicada previamente puede completarse con elementos condicionales. De hecho, el bucle precedente muestra sucesivamente los elementos contenidos dentro del bucle. SPIP permite además especificar lo que se muestra antes y después del bucle si hay varios resultados, y lo que se inserta si no hay ningún resultado.
Eso da:
<BBn>
* Código opcional anterior non conditional
<Bn>
* Código opcional anterior
<BOUCLEn(TYPE){critère1}{critère2}{...}{critèrex}>
* Código + balizas SPIP
</BOUCLEn>
* Código opcional posterior
</Bn>
* Código alternativo
<//Bn>
* Código opcional non conditional posterior
<//BBn>
El código opcional anterior (precedido por <Bn>
) solo se muestra si el bucle extrae por lo menos una respuesta. Se incluye antes de los resultados del bucle.
El código opcional posterior (que acaba por </Bn
) se muestra solamente si el bucle contiene por lo menos una respuesta. Se incluye después de los resultados del bucle.
El código alternativo (que acaba por <//Bn>
) se muestra en el lugar del bucle (y remplazando también los códigos opcionales anterior y posterior) si el bucle no encontró ningún resultado.
Por ejemplo, el código:
<B1>
Esta sección contiene los elementos siguientes:
<ul>
<BOUCLE1(ARTICLES){id_rubrique}>
<li>#TITRE</li>
</BOUCLE1>
</ul>
</B1>
Esta sección no contiene artículos.
<//B1>
da los resultados siguientes:
- si hay solamente un artículo:
Esta sección contiene los elementos siguientes:
<ul>
<li>Título del artículo</li>
</ul>
- si hay varios artículos:
Esta sección contiene los elementos siguientes:
<ul>
<li> Título del artículo 1</li>
<li> Título del artículo 2</li>
...
<li> Título del último artículo</li>
</ul>
- si no hay ningún artículo:
Esta sección no contiene ningún artículo.
Criterios de entorno en cascada
Cada bucle realiza la selección de los elementos extraídos de la base de datos en función de criterios. Estos criterios corresponden al entorno en el cual se encuentra el bucle.
Por ejemplo: si se considera un bucle del estilo «Mostrar los artículos incluidos en esta sección», es necesario saber de qué sección se trata. A esto es a lo que se llama el entorno.
- El entorno proporcionado por el URL
Cuando se visita una página de un sitio SPIP, su dirección contiene generalmente una variable. Por ejemplo:
- spip.php?page=rubrique.php&id_rubrique=15
o bien directamente spip.php?rubrique15
Esta variable define así un primer entorno: el bucle «Mostrar los artículos incluidos en esta sección» debe entenderse entonces como la «Mostrar los artículos de la sección 15».
Claramente, con el mismo código del esqueleto, si se llama la dirección:
- spip.php?rubrique7
la interpretación de este bucle se convertirá en «Mostrar los artículos de la sección 7».
- El entorno proporcionado por los demás bucles
Dentro de un bucle, el entorno se modifica para cada elemento del bucle. Al colocar bucles unos en el interior de otros, se heredan así entornos imbricados unos en otros.
Así, en la estructura siguiente:
<BOUCLE_articulos: mostrar los artículos de esta sección>
Mostrar el título del articulo
<BOUCLE_autores: mostrar las autoras de este artículo>
Nombre de la autora
</BOUCLE_autores>
</BOUCLE_articulos>
Debe entenderse que:
- el primer bucle (BOUCLE_articulos
) muestra los artículos en función de la sección, según el entorno que proporciona el URL (id_rubrique=15
por ejemplo);
- en este bucle, se obtienen uno o más artículos;
- «en el interior» de cada uno de estos artículos, hay un entorno diferente (el del artículo, es decir, por ejemplo, id_article=199
);
- el segundo bucle (BOUCLE_autores
), que se encuentra en el interior del primer bucle, depende para cada una de sus ejecuciones sucesivas (se ejecuta para cada uno de los artículos del primer bucle): «mostrar los autores de este artículo» se convierte sucesivamente en «mostrar los autores del primer artículo», «del segundo artículo» etcétera.
Como se ve, mediante el anidamiento de bucles sucesivos, se obtienen bucles distintos, incluidos unos en otros, que dependen de los resultados de los bucles en los que están situados. Y finalmente, el bucle inicial (el que contiene a todos los demás) depende de un parámetro fijado en la dirección de la página.
Bucles incluidos y bucles sucesivos
Si, como acabamos de ver, se pueden incluir bucles unos en otros (cada bucle incluido dependiente del resultado del bucle en cuyo interior está instalado), también se pueden instalar los bucles uno detrás de otro; sin que los bucles sucesivos influyan unos sobre otros.
Por ejemplo, la página de una sección está compuesta típicamente por los elementos siguientes:
<BOUCLE_seccion(RUBRIQUES){id_rubrique}>
<ul>Título de la sección
<BOUCLE_articulos(ARTICLES){id_rubrique}>
<li> Título del articulo</li>
</BOUCLE_articulos>
<BOUCLE_sub_secciones(RUBRIQUES){id_rubrique}>
<li> Título de la sub-sección</li>
</BOUCLE_sub_secciones>
</ul>
</BOUCLE_seccion>
<ul>No hay ninguna sección en esta dirección</ul>
<//B_seccion>
El primer bucle (BOUCLE_seccion
) depende de la variable pasada en el URL de la página (id_rubrique=15
por ejemplo).
Los bucles siguientes (BOUCLE_articulos
y BOUCLE_sub_secciones
) están en el interior del primer bucle. Si no existe una sección 15, el primer bucle no da ningún resultado (se muestra el código alternativo "No hay contenido de sección..."), y se ignoran totalmente los dos bucles incluidos. Pero si existe una sección 15, entonces se analizan los dos sub-bucles.
En cuanto a éstos, se presentan uno después del otro. Dependen de los resultados del bucle en el que se encuentran, pero son independientes uno de otro. Si no hay artículos en la sección 15 ((BOUCLE_articulos
), se mostrarán igual los títulos de las subsecciones de la sección 15 (BOUCLE_sub_secciones
), y a la inversa.
Contadores
Hay dos balizas que permiten contar los resultados en los bucles.
- #TOTAL_BOUCLE devuelve el número total de resultados mostrados por el bucle. Puede utilizarse en el bucle, en las partes opcionales - anterior y posterior - e incluso en la parte alternativa después del bucle.
Por ejemplo, para ver el número de documentos asociados con un artículo:
<BOUCLE_art(ARTICLES){id_article}>
<BOUCLE_doc(DOCUMENTS) {id_article}></BOUCLE_doc>
[hay (#TOTAL_BOUCLE) documento(s).]
<//B_doc>
</BOUCLE_art>
Cuidado: si la parte central del bucle no devuelve nada (como es el caso del bucle
<BOUCLE_doc>
anterior, que sólo sirve para contar el número de resultados), el#TOTAL_BOUCLE
sólo se podrá ver cuando esté en la parte alternativa posterior del bucle (<//B_doc>
).
- #COMPTEUR_BOUCLE devuelve el número de la iteración actual del bucle. Se puede utilizar, por ejemplo para numerar resultados:
<BOUCLE_art(ARTICLES) {par date} {inverse} {0,10}>
#COMPTEUR_BOUCLE - #TITRE<br>
</BOUCLE_art>