Справка
Язык шаблонизатора
Шаблоны могут быть написаны на PHP с использованием API, либо на специальном мета-языке системы. Предпочтителен именно второй подход, по следующим причинам:
- Исключая PHP мы загоняем разработчиков в рамки, не позволяющие выйти за установленные права доступа; Таким образом достигается большая безопасность при совместной разработке или при использовании сторонних решений;
- На каждом конкретном этапе разработки, автору предстоит выбрать из набора возможных команд;
- Команды абстрагированы от их реализации до уровня абстракции данных системы; Это даёт возможность оперировать объектами модуля напрямую из кода.
Структура шаблона
Шаблон представляет из себя текст (например, HTML код), в который вставлены специальные конструкции языка:
- Команды
- Условия
- Циклы
- Комментарии
- NoScript участки
- Блоки
- Инструкции для управления кешем
- Специальные секции
Команды шаблона
Команды указываются в виде цепочек операторов. Каждый следующий оператор продолжает действие, инициированное предыдущим (дополняя его).
Выбор следующего оператора для цепочки осуществляется в зависимости от типа результата, возвращённого предыдущим.
Команды в тексте записываются между квадратными скобками [ и ].
Если есть необходимость вставить в текст символ [ или ], то он записывается с помощью повторения: [[ и ]] соответственно.
Если есть необходимость множественного использования символов [ и ] в тексте, то такие участки рекомендуется обрамлять блоком NoScript (см. ниже).
Для редактирования шаблона предлагается использовать встроенный в административную панель системы визуальный редактор, который автоматически подставит [[ или ]] где это необходимо.
Условные выражения
Команда может быть частью условного выражения.
Логические операторы для И: and, &&
Логические операторы для ИЛИ: or, ||
Логические операторы для НЕ: !
Операторы сравнения:
A == B | A равно B |
A >= B | A больше или равно B |
A <= B | A меньше или равно B |
A < B | A меньше B |
A > B | A больше B |
A != B | A не равно B |
A^B | Поиск подстроки Строка B содержит подстроку A |
A^B | Поиск элемента массива Массив B содержит элемент A |
A^B:C | Поиск элемента массива по значению поля В массиве объектов B присутствует объект с полем C, значение которого равно A |
Команда, для обозначения правды: true либо любое не пустое значение
Команда, для обозначения лжи: false либо любое пустое значение
Математические выражения
Команда может быть частью математического оператора
Математические операторы:
A + B | “Умное” сложение, применяется для сложения строк, чисел и массивов. Если A массив, а B нет, то массив A пополнится элементом B. |
A +++ B | Сложение чисел A и B Если A или B не содержат число, то они заменяются нулём (можно использовать A+=B). |
A * B | Умножение A на B (можно использовать A*=B) |
A / B | Деление A на B (можно использовать A/=B) |
A // B | Целочисленное деление A на B |
A % B | Остаток от деления A на B |
A - B | Вычитание B из A (можно использовать A-=B) |
A ** B | A, возведённое в степень B |
A *> B | Добавление в массив A элемента B Можно использовать стандартные [a[]=b] |
A *> B:C | Добавление в массив A элемента C с ключом B Можно использовать стандартные [a[b]=c] |
A++ | Прибавить 1 к A |
A-- | Отнять 1 от A |
Строки
Строки допускается записывать в одинарных или двойных кавычках. Если есть необходимость разместить кавычку того же типа внутри строки, её необходимо экранировать символом \
Для сложения строк можно использовать обычный оператор сложения (+), либо использовать специальный оператор конкатенации ++
Спец.символы (указываются за пределами кавычек):
#13 - символ переноса каретки
#10 - символ конца строки
# - пробел
Числа
Можно указывать целые и дробные, положительные и отрицательные числа.
Десятичная часть дробных чисел указывается через точку.
Для определения отрицательного числа перед ним указывается знак минус.
Массивы
Для доступа к элементу массива по его индексу, необходимо указать индекс в квадратных скобках [ и ].
Кроме этого, получить доступ к элементу массива можно также, как к переменной объекта.
Существует поддержка многомерных массивов.
Создать массив можно просто перечислив его элементы через запятую в обычных скобках ( и ).
такая команда с одним элементом [X=( Y )] не вернёт массив, для этого воспользуйтесь командой array
Также создать массив можно при помощи команды array
здесь при помощи оператора => можно задать ключ для каждого элемента (ключ=>значение)
Значения для массивов устанавливаются также как и для обычных переменных.
Если необходимо добавить новый элемент без указания ключа, то просто не указывайте ключ в скобках.
Особенности
Регистр команд шаблона игнорируется (всё приводится к нижнему регистру перед интерпритацией).
Наборы команд могут быть разделены знаком ; и записаны в одних [ и ].
Кроме редких исключений, можно использовать произвольные отступы в командах.
[
X = Z + 10
]
Аргументы операторов могут быть записаны через запятую, или через пробел.
[some_operator(x, y, z)] или [some_operator(x y z)]
Аргументы функций, частей и блоков должны быть записаны с указанием наименования переменных в формате (VarName=VarValue, VarName=VarValue…)
Операторы могут быть сгруппированы с помощью скобок ( и ).
Существуют специальные команды, не возвращающие никакого результата:
- Операторы приравнивания [x='123']
- Установка значений в поля объектов [object.field=>'value']
- Подготовка значений перед добавлением/обновлением объекта ['field'->'value']
- Системные команды (выход из цикла, тип интерпретации и т.д.)
Условия
Условные операторы можно представить в виде двух типов записи: InLine и Block.
Тип InLine представляет из себя запись условия в виде оператора.
[ if(Condition,OnTrue,OnFalse) ]
Данный оператор вернёт OnTrue, если Condition истинно, либо OnFalse.
Тип Block записывается следующим образом:
[if Condition]
Текст с набором операторов
[/if]
Для указания действия при несоблюдении условия добавляется блок [else]
[if Condition]
Шаблон, обрабатываемый если условие соблюдено
[else]
Шаблон, обрабатываемый в противном случае
[/if]
Можно сгруппировать несколько условий с помощью [elseif]
[if Condition]
Соблюдено 1ое условие
[elseif Condition2]
Второе
[else]
Никакое
[/if]
Цикл перебора массива
Имеет блочный синтаксис:
[tree order deep array]
Тело перебора
[/tree]
Параметры order и deep являются необязательными.
Order - особый порядок перебора: rev - в обратном порядке, rand - в случайном порядке
Deep - глубина перебора. Если необходимо перебрать только элементы без их потомков, то необходимо написать linear, иначе же указать глубину перебора через deep(X), где X - максимальная глубина потомков перебираемых элементов.
Array - перебираемый массив.
Секция After отвечает за действие, выполняемое после перебора дочерних элементов текущего перебираемого объекта. Т.е. при возвращении глубины перебора на уровень выше.
[tree array]
Тело перебора
[after]
Действие, после перебора потомков
[/tree]
[tree pages]
<div class="elem">[cur.title]</div>
[if cur.sub]
<div class="section"> <!-- открываем секцию с подэлементами -->
[/if]
[after]
</div> <!-- закрываем секцию с подэлементами -->
[/tree]
Цикл перебора числа
[tree X..Y]
Тело перебора
[/tree]
или
[for X..Y]
Тело перебора
[/for]
Перебирает все целые числа от X до Y с интервалом 1.
Переменные и команды внутри цикла
current | Текущий перебираемый элемент (объект) |
count | Общее количество элементов перебора |
index | Номер текущей операции перебора (с нуля) |
key | Ключ текущего перебираемого элемента |
min | Число, с которого стартует цикл перебора числа |
max | Число, которым завершается цикл перебора числа |
value | Значение текущего перебираемого элемента |
step | Уровень вложенности текущего перебираемого элемента |
pass | Пропустить обход вложенного массива текущего элемента |
continue | Пропустить текущую итерацию цикла (можно вызывать с параметром continue($x), где $x - количество этапов, которое нужно пропустить |
break | Выйти из цикла |
first? | Это первый элемент цикла? |
last? | Это последний элемент цикла? |
Переключатель
[switch $var]
[case $value1]
Этот участок будет вызван если $var==$value1
[case $value2]
Этот участок будет вызван если $var==$value2
[default]
Этот участок будет вызван если $var не подойдёт ни к одному case-у
[/switch]
Условный цикл
[while Condition]
Тело перебора
[/while]
Цикл будет перебираться до тех пор, пока выполняется условие Condition
Комментарии
Для установки комментариев используется следующий синтаксис:
[* текст комментария *]
NoScript участки
Участки текста, в содержимом которых не будет производиться поиск операторов. Соответственно, в них можно свободно использовать квадратные кавычки [ и ].
Синтаксис: [~ текст ~]
Silent участки
Участки текста, которые не будет отправлены клиенту.
Синтаксис: [silent] этот текст пользователь не увидит [/silent]
Специальные секции
Секция Head
Переносит данные, заключённые в неё, в подвал секции head HTML файла. Данные из нескольких секций складываются.
Синтаксис: [head] этот текст попадёт в секцию head [/head]
Секция Compile
Позволяет сгруппировать CSS стили (а также JS скрипты) в один файл, который автоматически подключается к текущему документу. Данные из нескольких секций складываются.
С помощью этой секции можно компилировать LESS в CSS.
Можно указать дополнительный флаг u ([compile css u]) для того, чтобы исключить дубли.
Синтаксис:
[compile css] стиль, размещённый здесь, попадёт в файл CSS, подключённый к текущей страницы [/compile]
[compile less] сгенерирует CSS из LESS, добавит его в подключённый к текущей странице файл CSS [/compile]
[compile js u] скрипт, размещённый здесь, попадёт в файл JS, подключённый к текущей страницы [/compile]
Блоки
Блоки служат аналогами функций. Их необходимо использовать для дублирования часто повторяющегося текста или операции.
Синтаксис блоков состоит из двух частей - определение и вызов.
Определение блока:
[block name="some name" silent]
Содержимое блока
[/block]
Параметр name задаёт имя блоку и является необязательным.
По умолчанию содержимое блока исполнится и при его определении. Для того, чтобы этого избежать, необходимо указать параметр silent.
Вызов блока: [block.name]
При вызове, можно указать специфические переменные для блока:
[block.name(var1=value1, var2=value2)]
Для идентификации блоков редактором, можно добавлять поле title="название для редактора" и флаг hidden (для скрытия из редактора).
Наследование шаблонов с помощью блоков
Шаблон-родитель может содержать множество блоков, значение которых может перекрыть шаблон-потомок.
Шаблон-потомок (это может быть как отдельная часть, так и её сегмент, например, тело цикла или тело условия) содержит специальную команду [use tpl] и набор блоков.
Прочие элементы, находящиеся вне блоков, игнорируются. Также игнорируется содержимое, сгенерированное до определения [use tpl].
Для того, чтобы потомок мог разместить контент вне шаблона, оператор [use] и все переопределённые блоки можно завернуть в отдельный блок. Т.е. команда [use], размещённая внутри блока будет распространяться только на этот блок.
Для того, чтобы разместить в блоке потомка контент из блока родителя, необходимо использовать следующую команду: [parent_block_content] (также существуют команды [parent_part] и [parent_part_code] для запуска блока родительского шаблона или для доступа к его коду).
Принцип действия: шаблон-потомок вызывает родительский шаблон с заменой некоторых его блоков на собственные значения.
Синтаксис:
[use type value]
Где type может принимать следующие значения:
module | mod | Выбрать шаблон из части текущего модуля. Value указывает на спец.имя нужной части |
up | Выбрать вышестоящую часть (если такая имеется) в рамках текущего модуля |
function | func show component form | Выбрать шаблон из компонентов. Value указывает на спец.имя нужного компонента Type указывает на его тип (функция, отображение, компонент, форма) |
tpl | Использовать шаблон, содержащийся в Value. Позволяет использовать элементы модели для определения шаблона |
Рассмотрим следующий пример
Шаблон-родитель
Текст до вставки
[block name="content"]
Старый контент
[/block]
Текст после вставки
</div>
Шаблон-потомок
[block.name="content"]
Новый контент
[/block]
Результат выполнения
Текст до вставки
Новый контент
Текст после вставки
</div>
Видео
Читать далее про "Операторы"