Управляющие конструкции

В шаблонах уведомлений могут использоваться следующие управляющие конструкции:

1. Объявление собственных макросов

В случае необходимости можно определять собственные макросы прямо в шаблоне. Для этого используется конструкция

<def NAME=DATA>

где NAME – имя макроса (без символа$), DATA – новое значение макроса.

Имя макроса может состоять из символов диапазона [a-zA-Z_-]. Новое значение макроса можно заключать в кавычки. Символ, следующий сразу за косой чертой "\", воспринимается непосредственно (т.е. таким образом можно добавить, к примеру, обратную угловую скобку).

Пример:

<def MY_MACROS="\<my macros\>">

В данном случае определяется макрос $MY_MACROS$, содержащий '<my macros>'.

2. Включение содержимого внешних файлов

В шаблон может быть включено содержимое внешнего файла, для чего используется директива

<include FILENAME>

где FILENAME – имя и путь к файлу относительно значения, заданного в макросе $TEMPLATES_DIR$. Имя и путь к файлу можно заключать в кавычки. Символ, следующий сразу за косой чертой "\", воспринимается непосредственно (т.е. таким образом можно добавить, к примеру, обратную угловую скобку).

Пример:

<include "style.css">

В данном случае при генерации письма вместо директивы будет вставлен текст из файла style.css.

3. Условные операторы

В шаблонах можно использовать условные операторы. Они определяются следующей конструкцией:

<if NAME [ ( '==' | '!=' ) DATA ] >
TEXT
</if>

где NAME – имя макроса, DATA – регулярное выражение для проверки его значения (используются регулярные выражения Perl), а TEXT – текст, который будет вставлен в письмо в случае истинности условия. В условиях используются два типа операторов сравнения:

== - Истина, если значение макроса соответствует регулярному выражению;

!= - Истина, если значение макроса не соответствует регулярному выражению.

Если часть конструкции, приведенная в квадратных скобках, не указана (т.е. указывается условие <if NAME>), то это аналогично записи: <if NAME != "" >.

Допускается использование вложенных условных операторов и циклов (см. ниже). Если внутри оператора находится директива определения нового макроса def, то новый макрос будет определяться, только если условный оператор выполняется. При этом новое значение макроса сохранится и после выхода из условного оператора и будет доступно для использования ниже.

Пример:

<def N="n123">
<if N>N is not empty!</if>
<if N == "n.*">N stars with n!</if>
<if N != n123>WRONG!<\if>

В письме, сгенерированном на основе такого шаблона, окажутся строки:

N is not empty!
N starts with n!

3. Циклы

В шаблонах также могут быть использованы циклы. Цикл описывается конструкцией вида:

<for NAME;LIST [ ( '==' | '!=' ) DATA ; [DELIM] ] >
TEXT
</for>,

Где

NAME – имя макроса, который будет использован в роли локальной переменной в теле цикла. На каждой итерации цикла ему будет присвоено очередное значение, извлеченное из LIST.

LIST – Макрос, используемый в качестве списка значений для локальной переменной цикла. Макрос спискового типа. В данном случае может быть указан любой макрос, при этом, если он имеет не списковый тип, то будет преобразован к нему посредством разбивки строки по запятым.

DATA – Регулярное выражение для проверки и выбора значений из списка на каждой итерации цикла.

DELIM – разделитель, вставляемый в тело генерируемого письма между фрагментами текста, сгенерированными на каждой итерации цикла.

Если значения, приведенные в квадратных скобках, не указаны, это аналогично записи <for NAME;LIST == ".*" >, т.е. из LIST берутся все значения.

В противном случае каждое значение из LIST сравнивается с регулярным выражением, указанным в DATA, и если результат сравнения истинный (== - соответствует, а != - не соответствует), то очередное значение присваивается макросу NAME и происходит итерация цикла. Если указан разделитель DELIM, то между каждой итерацией в генерируемое письмо вставляется значение, указанное как разделитель.

Обработка циклов происходит следующим образом:

1)Для каждого выбранного NAME генерируется текст

<def NAME="LIST_VAL">
TEXT DELIM,

где LIST_VAL – следующее значение, выбранное из LIST, а TEXT – текст, указанный в теле цикла.

2)Для этого текста вызывается синтаксический анализатор, результат работы которого помещается в генерируемое письмо сразу после метки <\for>.

3)Данная операция выполняется для каждого выбранного значения из LIST.

4)Конструкция цикла удаляется из генерируемого письма и синтаксический анализатор начинает повторно разбирать сформированный циклом текст.

Пример:

<def RCPTS="root@localhost, test@mydoamin.com">
<for RCPT;RCPTS==".*";", "><a href="mailto:$RCPT$">$RCPT$</a></for>

В результате обработки этой конструкции будет получен следующий текст:

<a href="mailto:root@localhost">root@localhost</a>,
<a href="mailto:test@mydoamin.com">test@mydoamin.com</a>

Все ключевые слова def, if и for являются регистронезависимыми.