Справка

Язык шаблонизатора

Перейти к видео

Шаблоны могут быть написаны на PHP с использованием API, либо на специальном мета-языке системы. Предпочтителен именно второй подход, по следующим причинам:

  1. Исключая PHP мы загоняем разработчиков в рамки, не позволяющие выйти за установленные права доступа; Таким образом достигается большая безопасность при совместной разработке или при использовании сторонних решений;
  2. На каждом конкретном этапе разработки, автору предстоит выбрать из набора возможных команд;
  3. Команды абстрагированы от их реализации до уровня абстракции данных системы; Это даёт возможность оперировать объектами модуля напрямую из кода.

Структура шаблона

Шаблон представляет из себя текст (например, HTML код), в который вставлены специальные конструкции языка:

  • Команды
  • Условия
  • Циклы
  • Комментарии
  • NoScript участки
  • Блоки
  • Инструкции для управления кешем
  • Специальные секции

Команды шаблона

Команды указываются в виде цепочек операторов. Каждый следующий оператор продолжает действие, инициированное предыдущим (дополняя его).

Например, оператор rows выдаст все объекты таблицы, а если его уточнить оператором first (получится rows.first), то команда вернёт первый объект.

Выбор следующего оператора для цепочки осуществляется в зависимости от типа результата, возвращённого предыдущим.

Например, цепочка rows.first выдаст первый объекты таблицы “Новости”, а если его уточнить оператором title (rows.first.title), то команда вернёт содержимое поля title первого объекта “Новостей”. Таким образом мы видим, что шаблонизатор интегрируется с структурой данных модуля.

Команды в тексте записываются между квадратными скобками [ и ].
Если есть необходимость вставить в текст символ [ или ], то он записывается с помощью повторения: [[ и ]] соответственно.
Если есть необходимость множественного использования символов [ и ] в тексте, то такие участки рекомендуется обрамлять блоком NoScript (см. ниже).

Для редактирования шаблона предлагается использовать встроенный в административную панель системы визуальный редактор, который автоматически подставит [[ или ]] где это необходимо.

Условные выражения

Команда может быть частью условного выражения.

Например: [X or Y and Z.first.in_navigation]

Логические операторы для И: and, &&
Логические операторы для ИЛИ: or, ||
Логические операторы для НЕ: !

Операторы сравнения:

A == BA равно B
A >= BA больше или равно B
A <= BA меньше или равно B
A < BA меньше B
A > BA больше B
A != BA не равно B
A^BПоиск подстроки
Строка B содержит подстроку A
A^BПоиск элемента массива
Массив B содержит элемент A
A^B:CПоиск элемента массива по значению поля
В массиве объектов B присутствует объект с полем C, значение которого равно A

Команда, для обозначения правды: true либо любое не пустое значение

Команда, для обозначения лжи: false либо любое пустое значение

Математические выражения

Команда может быть частью математического оператора

Например: [2 + rows.first.price / 2]

Математические операторы:

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 ** BA, возведённое в степень B
A *> BДобавление в массив A элемента B
Можно использовать стандартные [a[]=b]
A *> B:CДобавление в массив A элемента C с ключом B
Можно использовать стандартные [a[b]=c]
A++Прибавить 1 к A
A--Отнять 1 от A

Строки

Строки допускается записывать в одинарных или двойных кавычках. Если есть необходимость разместить кавычку того же типа внутри строки, её необходимо экранировать символом \

Например: [ ' it\'s some text ' ]

Для сложения строк можно использовать обычный оператор сложения (+), либо использовать специальный оператор конкатенации ++

Например: [ 'String 1' ++ 'String 2' ]

Спец.символы (указываются за пределами кавычек):
#13 - символ переноса каретки
#10 - символ конца строки
# - пробел

Числа

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

Массивы

Для доступа к элементу массива по его индексу, необходимо указать индекс в квадратных скобках [ и ].

Кроме этого, получить доступ к элементу массива можно также, как к переменной объекта.

Например: [ X . A ] будет соответствовать [ X[A] ]

Существует поддержка многомерных массивов.

Например: [ X[A][B] ]

Создать массив можно просто перечислив его элементы через запятую в обычных скобках ( и ).

Например: [ X = ( Y, Z, A, B, C) ],
такая команда с одним элементом [X=( Y )] не вернёт массив, для этого воспользуйтесь командой array

Также создать массив можно при помощи команды array

Например: [ X = array( A, B=>C ) ]
здесь при помощи оператора => можно задать ключ для каждого элемента (ключ=>значение)

Значения для массивов устанавливаются также как и для обычных переменных.

Например: [ X[i] = A ]

Если необходимо добавить новый элемент без указания ключа, то просто не указывайте ключ в скобках.

Например: [ X[] = A ]

Особенности

Регистр команд шаблона игнорируется (всё приводится к нижнему регистру перед интерпритацией).

Наборы команд могут быть разделены знаком ; и записаны в одних [ и ].

Например: [Operator1; Operator2;]

Кроме редких исключений, можно использовать произвольные отступы в командах.

Например:
[
      X = Z + 10
]

Аргументы операторов могут быть записаны через запятую, или через пробел.

Например:
[some_operator(x, y, z)] или [some_operator(x y z)]

Аргументы функций, частей и блоков должны быть записаны с указанием наименования переменных в формате (VarName=VarValue, VarName=VarValue…)

Например: [function.abc(var1=X, var2=Y)]

Операторы могут быть сгруппированы с помощью скобок ( и ).

Например: [ ( (1 + 5) * 2 > 3 ) OR !( X++Y ) ]

Существуют специальные команды, не возвращающие никакого результата:

  • Операторы приравнивания [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.
Позволяет использовать элементы модели для определения шаблона

Рассмотрим следующий пример

Шаблон-родитель

<div>
      Текст до вставки
      [block name="content"]
            Старый контент
      [/block]
      Текст после вставки
</div>

Шаблон-потомок

[use up]
[block.name="content"]
      Новый контент
[/block]

Результат выполнения

<div>
      Текст до вставки
      Новый контент
      Текст после вставки
</div>

Видео



Читать далее про "Операторы"