Основы синтаксиса
Цикл в упрощенном виде записывается так:
<BOUCLEn(TYPE){criterion1}{criterion2}...{criterionX}>
* HTML код HTML + SPIP теги
</BOUCLEn>
Ранее, на странице Циклы и Теги, говорилось, что HTML код + SPIP теги выводятся ровно столько раз, сколько записей из базы выводит цикл. Он может вывести несколько записей, одну или не вывести вообще ничего.
Обратите внимание на строку в примере:
<BOUCLEn(TYPE){criterion1}{criterion2}...{criterionX}>
- Слово BOUCLE
(по французски «цикл») определяет новый цикл в SPIP. Директива пишется именно таким образом и никак иначе: все циклы в SPIP должны начинаться с директивы BOUCLE
.
- n - это имя цикла. Оно должно быть уникальным в текущем файле: если в одном файле у вас будет два цикла с одинаковыми названиями, SPIP выдаст ошибку при попытке выполнить шаблон. Название может состоять из латинских букв, цифр и нижнего подчеркивания. Название цикла может быть произвольным, но рекомендуется начинать его с нижнего подчеркивания и давать название по сути. Чуть позже будет показано, как можно использовать несколько циклов в одном шаблоне.
Если название цикла состоит только из цифр, то вы можете не использовать нижнее подчеркивание, например: вы хотите дать циклу имя 5, то он будет выглядеть следующим образом:
<BOUCLE5...>
...
</BOUCLE5>
Но если вы используете буквы в названии цикла, то имя должно начинаться с нижнего подчеркивания - “_”. Например:
<BOUCLE_subsections...>
...
</BOUCLE_subsections>
- Элемент цикла (TYPE)
задает, какую именно информацию необходимо вывести из базы данных. Порядок написания элемента играет важную роль: TYPE
должен находится между круглыми скобками, без пробелов и написан заглавными (большими) буквами. В общем случае список возможных значений ограничен и состоит из перечня объектов в CMS SPIP: ARTICLES, RUBRIQUES, AUTEURS, BREVES, etc. (список есть в этой документации)[NB: на самом деле (TYPE) указывает, из какой таблице в базе данных необходимо получать информацию. Таким образом, если у вас в одной базе данных содержаться другие таблицы, кроме SPIP (например phpBB), то вы можете при помощи циклов строить запросы и выводить содержимое этих таблиц. Посмотрите дополнительную документацию в английском разделе сайта, к сожалению пока перевод этих материалов не планируется.].
Расширим наш пример:
<BOUCLE_subsections(RUBRIQUES)...>
...
</BOUCLE_subsections>
- Критерии записываются в фигурных скобках {criterion1}{criterion2}...
. Критерии необходимы для того, чтобы сказать SPIP, какие именно записи необходимо вывести из базы данных в данном цикле. Критерии задают признаки, по которым выбирается информация (записи) из базы данных. С их помощью можно определять порядок вывода (сортировку) элементов: статьи можно сортировать по дате, по первым буквам в названии и т.д... Можно задавать количество элементов, которые будут выведены, например, первые десять или же вторая половина всех статей в разделе.
Комбинируя разные критерии можно достаточно просто конструировать циклы, которые соответствуют сложным SQL запросам.
Пример цикла, который выводит пять последних статей текущего автора:
<BOUCLE_same_author(ARTICLES){id_auteur}{par date}{inverse}{0,5}>
...
</BOUCLE_same_author>
В данной документации описаны критерии для каждого вида циклов (ARTICLES, RUBRIQUES etc), но многие критерии универсальны для всех циклов.
Полный синтаксис цикла
Полная запись цикла выглядит так:
<Bn>
* опциональный HTML код до цикла (HTML, циклы и теги)
<BOUCLEn(TYPE){criterion1}{criterion2}...{criterionX}>
* результат цикла (HTML код + SPIP теги)
</BOUCLEn>
* опциональный HTML код после цикла (HTML, циклы и теги)
</Bn>
* замещающий (альтернативный) код, который выполняется если цикл не вернул ни одной записи (HTML, циклы и теги)
<//Bn>
Опциональный код “до” (пишется сразу после директивы <
B
n
>
) показывается, если цикл нашел хотя бы одну запись, которая соответствует заданным критериям - когда выводится минимум одна запись. Опциональный код выводится перед результатами цикла.
Опциональный код “после” (оканчивается директивой <
/B
n
>
) выводится в случае, если цикл вернул хотя бы одну запись. Код показывается сразу же после вывода цикла.
Замещающий (альтернативный) код (заканчивается директивой <
//Bn
>
) выводится в том случае, если цикл не нашел ни одной записи, которая соответствует заданным критериям. В том случае опциональный код "до и после" не выводится; он полностью замещается альтернативным кодом.
Пример цикла, который выводит все статьи в разделе:
<B1>
Статьи в разделе:
<ul>
<BOUCLE1(ARTICLES){id_rubrique}>
<li>#TITRE</li>
</BOUCLE1>
</ul>
</B1>
В разделе нет статей.
<//B1>
В зависимости от количества статей в разделе, вывод цикла будет разным:
- Если в разделе только одна статья:
Статьи в разделе: <ul> <li>Название статьи</li> </ul>
- Если в разделе несколько статей:
Статьи в разделе: <ul> <li>Название первой статьи</li> <li>Название второй статьи</li> ... <li>Название последней статьи</li> </ul>
- Если в разделе нет статей:
В разделе нет статей.
В опциональный код (до и после цикла или замещающий) кроме HTML тегов можно записывать другие циклы или теги SPIP. Теги, которые должны вывестись в результатах цикла, нельзя использовать для вывода; причину проще пояснить на примере:
<Bn> #TITRE <BOUCLEn(ARTICLES) {id_rubrique}> #TITRE </BOUCLEn>
Данный цикл выводит все статьи из раздела. Если статей несколько, то SPIP не будет знать, название какой из статей вывести до цикла. Потому в текущей и более ранних версиях принципиально невозможно выводить полученные теги иначе, как в результатах цикла.
Сокращенная запись цикла
Начиная с SPIP 2.0, в некоторых случаях возможно использовать сокращенную запись цикла..
Если вы хотите вывести только количество записей, которые нашел цикл (при помощи тега #TOTAL_BOUCLE), код можно записать следующий образом:
<BOUCLE_a(ARTICLES) />#TOTAL_BOUCLE<//B_a>
вместо:
<BOUCLE_a(ARTICLES) > </BOUCLE_a>#TOTAL_BOUCLE</B_a>
Можно использовать такую запись, для того, что бы сформировать список повторяющихся материалов (см. критерий "doublons"):
<BOUCLE_a(ARTICLES) {criteria ...} {doublons}/>
В цикле не обязательно указывать все опциональные элементы.
Пример: цикл выводит название статьи с номером 1, а если ее нет, то содержимое файла с 404 ошибкой.
<BOUCLE_main(ARTICLES) {id_article=1}>
#TITRE
</BOUCLE_main>
<INCLURE {fond=404}>
<//B_main>
Как видно из примера, не обязательно использовать элементы <B_main>
и </B_main>
если кроме вывода результатов цикла необходим только замещающий код.
Критерии и окружение
Ранее рассказывалось о том, что указывает циклу, какую именно информацию необходимо вывести из базы данных. Работа некоторых критериев зависит от окружения, в котором находится цикл.
Например, если у нас есть цикл, который выводит все статьи из текущего раздела, то надо знать, какой именно из всех разделов сайта является текущим. Именно это и определяется окружением.
Цикл:
<BOUCLE_articles(ARTICLES) {id_rubrique}>
#TITRE<br />
</BOUCLE_articles>
- Использование URL для инициализации окружения
URL(адреса) страниц сайта на SPIP содержат переменные, конечно же, если не используется формирование ЧПУ формирование URL на основании названия материала.
Пример:
spip.php?rubrique15
(до версии SPIP 1.9, URL выглядел так: rubrique.php3?id_rubrique=15
)
Переменная в ссылке (id_rubrique) определяет окружение страницы. В этом случае наш цикл вывести все статьи из текущего раздела превращается в вывести все статьи из 15 раздела.
И если вы перейдете на страницу другого раздела, шаблон которого содержит такой же цикл, по ссылке:.../spip.php?rubrique7
то цикл выведет все статьи из раздела 7.
Т.е. цикл берет значение для критерия id_rubrique из своего окружения, в данном случае - из URL страницы.
В URL мы можем передавать практически любое количество параметров, которые необходимы для правильной работы циклов в шаблоне. Например, если нам необходимо вывести все статьи из раздела, у которых есть ключевые слова и они созданы на определенном языке. Цикл будет выглядеть так:
<BOUCLE_advanced(ARTICLES) {id_rubrique} {id_mot} {lang}>
#TITRE
</BOUCLE_advanced>
А ссылка, которая инициализирует шаблон, может иметь следующий вид:
/spip.php?rubrique7&id_mot=1&lang=ru
Если нам необходимо передать несколько значений одного и того же параметра, например, надо вывести статьи у которых есть не один ключ, а хотя бы один из нескольких, то ссылка будет иметь следующий вид
/spip.php?rubrique7&id_mot[]=1&id_mot[]=6& ....
. Правда, критерии цикла надо будет записать чуть иначе, но это отдельная история.
- Инициализация окружения другими циклами
В случае, если один цикл находится внутри другого, то окружение внутреннего цикла инициализируется результатами, полученными во внешнем цикле.
Рассмотрим подробнее пример вложенного цикла:
<BOUCLE_articles(ARTICLES) {id_rubrique}>
#TITRE (название статьи)
<BOUCLE_authors(AUTEURS) {id_article}>
#NOM (имя автора)
</BOUCLE_authors>
</BOUCLE_articles>
Вы видите, что:
- первый цикл (BOUCLE_articles
) выводит все статьи из текущего раздела. Номер текущего раздела цикл взял из URL (например id_rubrique=15
);
- результатом выполнения цикла является одна или несколько статей;
- каждый раз, когда выполняется цикл BOUCLE_articles
, он задает окружение для внутреннего цикла - это данные о текущей выведенной статье (к примеру id_article=199
);
- внутренний цикл (BOUCLE_authors
) будет выполнятся каждый раз, когда BOUCLE_articles
будет выводить одну статью. А так как с выводом каждой новой статьи у нас будет соответственно изменятся окружение. Тогда BOUCLE_authors
который выводит автора текущей статьи, с каждым выполнением внешнего цикла будет трансформироваться в "вывести автора первой статьи раздела", "вывести автора второй статьи раздела" и так далее.
С помощью вложенных циклов можно создавать очень полезные конструкции - внутренний цикл использует результаты работы внешнего цикла, а самый верхний получает исходные данные из одного или нескольких параметров, заданных в URL страницы.
Несколько вложенных циклов
Если во внешнем цикле находятся несколько других циклов, то они не влияют на окружение друг друга.
Пример:
<BOUCLE_section(RUBRIQUES){id_rubrique}>
<ul>Название раздела
<BOUCLE_articles(ARTICLES){id_rubrique}>
<li>Название статьи</li>
</BOUCLE_articles>
<BOUCLE_subsections(RUBRIQUES){id_rubrique}>
<li>Название подраздела</li>
</BOUCLE_subsections>
</ul>
</BOUCLE_section>
<ul>Раздела по этому адресу не существует</ul>
<//B_section>
Окружение внешнего цикла BOUCLE_section
задается через URL. В ссылке содержится номер раздела, из которого надо вывести информацию (id_rubrique=15
).
Другие циклы (BOUCLE_articles
и BOUCLE_subsections
) расположены внутри первого цикла. Если 15 раздела не существует, то внешний цикл не вернет никаких результатов (выведется замещающий код "Раздела по этому адресу не существует"). Соответственно, внутренние циклы не будут выполнены. Если 15 раздел существует, то внутренние циклы выполнятся.
Оба внутренних цикла зависят от внешнего (инициализируют окружение внешним циклом), но в тоже время полностью независимы друг от друга. Даже если один цикл не выполнится (например, в разделе не будет статьей), то выполнится второй.
Счетчики
Для того, чтобы определить и вывести количество найденных и выведенных элементов, используются два тега:
- #TOTAL_BOUCLE выводит общее количество записей, которые нашел (и вывел) цикл. Тег можно использовать в любой части цикла - в опциональном коде до и после результатов цикла, в замещающем коде и, собственно, в результатах. Обычно тег использует до или после вывода результатов цикла, так как если его поместить в основную часть цикла, то он выведется столько раз, сколько раз выполнится цикл.
Пример - вывод количества файлов, добавленных к статье:
<BOUCLE_art(ARTICLES){id_article}>
<BOUCLE_doc(DOCUMENTS) {id_article}></BOUCLE_doc>
[Всего (#TOTAL_BOUCLE) файлов.]
<//B_doc>
</BOUCLE_art>
Замечание: если в результатах цикла нет никакого кода, как в примере выше (
<BOUCLE_doc>
), тогда тег#TOTAL_BOUCLE
должен быть помещен в другой части следующего основного цикла (между</BOUCLE_doc>
и<//B_doc>
).
- #COMPTEUR_BOUCLE показывает сколько раз выполнился цикл. Он увеличивается на единицу с каждым выполнением цикла. Начальное значение #COMPTEUR_BOUCLE - 1. Его можно использовать для того, что бы нумеровать результаты вывода:
<BOUCLE_art(ARTICLES) {par date} {inverse} {0,10}>
#COMPTEUR_BOUCLE - #TITRE<br>
</BOUCLE_art>
Очень часто тег используется для того, чтобы задавать разные стили одинаковым блокам. Например, в разделе есть четыре подраздела. Название каждого подраздела должно быть разным цветом. Для этого мы создаем 4 разных класса: title1, title2, title3, title4.
Тогда наш цикл будет выглядеть так:
<BOUCLE_subrubriques(RUBRIQUES) {id_parent=#ID_PARENT}>
<div class="title#COMPTEUR_BOUCLE">#TITRE</div>
</BOUCLE_subrubriques>
а результат выполнения:
<div class="title1">Первый подраздел</div>
<div class="title2">Второй подраздел</div>
<div class="title3">Третий подраздел</div>
<div class="title4">Четвертый подраздел</div>