Изменения

Перейти к: навигация, поиск

Шаблонизатор VMX::Template

6783 байта добавлено, 00:44, 4 января 2011
м
Нет описания правки
== Идеи ==
Уйти от assign_vars(), assign_block_vars(). Передавать, как и в обычных движках, просто хеш с данными $vars. Как, например, в {{CPAN|Template::Toolkit}}. При этом сохранить данные методы для совместимости.
Почистить синтаксис: ликвидировать «преобразования», «вложенный путь по переменной» (->key->index->key->и т. п.), специальный синтаксис для окончания SET, неочевидное обращение к счётчику block.#, tr_assign_* и т. п.
Добавить обработку ошибок и диагностические сообщения.
 
== Использование (PHP) ==
 
<source lang="php">
require_once 'template.php';
 
# Конструктор
$template = new Template(array(
'root' => '.', # директория с шаблонами
'cache_dir' => './cache', # директория для кэширования компилированного кода шаблонов
'print_error' => true, # если true, ошибки компиляции выводятся на STDOUT
'raise_error' => false, # если true, при ошибке компиляции вызывается die()
'reload' => 1, # если 0, шаблоны не будут перечитываться с диска, и вызовов stat() происходить не будет
# 'use_utf8' => undef, # (только Perl) шаблоны в UTF-8 и с флагом UTF-8 = On
'begin_code' => '<!--', # маркер начала директивы кода
'end_code' => '-->', # маркер конца директивы кода
'eat_code_line' => true, # (похоже на TT CHOMP) съедать "лишний" перевод строки, если в строке только директива?
'begin_subst' => '{', # маркер начала подстановки выражения
'end_subst' => '}', # маркер конца подстановки выражения
'compiletime_functions' => # дополнительные компилируемые функции
array('func' => callback), # массив вида имя функции (в шаблонах) => callback,
# которому передаются скомпилированные выражения всех аргументов
# немного legacy, устаревшее:
'wrapper' => NULL, # если равно чему-то, что можно вызвать, через это будет
# пропущен вывод всех шаблонов ("глобальный фильтр")
'strict_end' => false, # требовать <!-- END имя_блока --> после <!-- BEGIN имя_блока -->
));
 
# Присвоение одной переменной:
$template->vars("ключ", "значение")
 
# Присвоение кучи переменных:
$template->vars(array("ключ" => "значение", ...));
# Выполнение шаблона и получение результата:
# (возможно с передачей целого хеша данных)
$page = $template->parse('имя_файла' [, array("ключ" => "значение", ...)]);
 
# Аналогично выполнение именованного блока из файла:
$page = $template->parse('имя_файла', 'имя_блока' [, array("ключ" => "значение", ...)]);
# Аналогично выполнение кода из строки:
$page = $template->parse(NULL, 'код' [, 'имя_блока'] [, array("ключ" => "значение", ...)]);
# Очистка сохранённых данных для генерации ещё одной страницы:
$template->clear;
</source>
== Реализация ==
<pre>
<!-- FOR var = block expression -->
...
<!-- END -->
</pre>
Причём, если <tt>expression ::= block</tt>, то <tt>var</tt> может быть само <tt>block</tt>'ом. Это, по сути, и есть то, что делает BEGIN: <!-- BEGIN block --> эквивалентно <!-- FOR block = block -->. Предыдущее значение переменной цикла после выхода из цикла всегда восстанавливается.
К номеру итерации можно обратиться через '''<tt>{var#}</tt>'''.
<pre><!-- IF OR(function(block.key1),AND(block.key2,block.key3)) --></pre>
 
Почему? Тут всё просто — основываясь на предположении, что длинные выражения в шаблонах нужны очень редко, было лениво писать нормальную грамматику для разбора обычных выражений. Почему они нужны редко? Да просто минимум логики в шаблонах — признак хороших шаблонов. А функции покрывают сразу и выражения, и «фильтры», и методы объектов.
Синтаксис вызова функции нескольких аргументов:
{s block.key}
</pre>
 
Синтаксис вызова метода объекта:
 
<pre>
{object.method()}
{object.method(arg1, arg2)}
{call(object, "method")}
{call(object, "method", array(arg1, arg2))}
</pre>
 
Последние два применения — как нетрудно заметить, обращение к функции call() и служат для вызова метода по вычисляемому имени.
 
Цепочки вызовов методов типа <tt>object.method().another_method()</tt> не поддерживаются, ибо к ним без сохранения звеньев нервно относится даже сам PHP.
=== IF ===
Включение другого шаблона также осталось:
<pre><!-- INCLUDE another-file.tpl --><!-- INCLUDE "another-file.tpl" --></pre> По «динамическому» имени шаблона включение производится функцией <tt>INCLUDE</tt> (она же <tt>PARSE</tt>). Как несложно заметить, вторая строка — как раз вызов функции. === Блоки === Блок — это часть шаблона, выделенная в отдельную «функцию», хорошо кэшируемая и предназначенная для повторного вызова из других мест. Покрывает сразу несколько вещей — «блоки», «макросы» и «обёртки» из TT. Да-да, TT славится бессмысленным дублированием функционала. Но имеет несколько преимуществ:* блоки, определённые в одном шаблоне, можно смело вызывать из других по имени файла + имени блока!* блок можно определить просто как некоторое выражение.* блоки хорошо кэшируются — с VMX::Template вы не испытаете разочарования, если вызовете какой-нибудь блок 1000 раз. В отличие от TT. Блоки в шаблоне не могут быть вложенными, а циклы, SET и прочие вещи, их оборачивающие, не имеют на них никакого влияния. После компиляции блоки просто вырезаются и преобразуются в отдельные функции PHP/Perl’а. <pre><!-- BLOCK имя_блока -->...код...<!-- END --></pre> или <pre><!-- BLOCK имя_блока = выражение --></pre> Вместо слова <tt>BLOCK</tt> можно также использовать слово <tt>FUNCTION</tt> или <tt>MACRO</tt>.
По «динамическому» имени Вызывать блок из шаблона включение производится функцией <tt>следует с помощью функции [[#INCLUDE</tt> (она же <tt>= PROCESS = PARSE</tt>)|PROCESS]].Вызывать блок из кода следует с помощью
== Функции ==

Навигация