Изменения

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

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

2515 байтов добавлено, 20:43, 27 июля 2018
Нет описания правки
'''VMX::Template''' — простой и высокопроизводительный шаблонизатор, имеющий Perl- и PHP-версии (основная — в данный момент PHP).
* Лицензия: GNU GPL версии 3 или новее
* Исходники Полный набор исходников здесь: http://yourcmc.ru/git/vitalif/VMXTemplate** PHP-версия (PHP >= 5.4): {{SVN|[http://yourcmc.ru/git/vitalif/trunkVMXTemplate/Templateraw/master/}} — для работы нужны файлы template.php template.php] и [http://yourcmc.ru/git/vitalif/VMXTemplate/raw/master/template.parser.phptemplate. Исходник грамматики в parser.php].** Новая Perl-версия: [{{SVN|http://yourcmc.ru/git/vitalif/trunkVMXTemplate/Templateraw/templatemaster/VMXTemplate.lime}} templatepm VMXTemplate.limepm]и все его [http://yourcmc.ru/git/tree/VMXTemplate.git/master/VMXTemplate подмодули VMXTemplate/*.pm].* Исходники (* Старая Perl), несколько устаревшие-версия: [{{SVN|vitaphotohttp:/solstice/lib-swayyourcmc.ru/VMXgit/Templatevitalif/VMXTemplate/raw/master/VMX%2FTemplate.pm}} VMX/Template.pm], и [{{SVN|vitaphotohttp:/solstice/lib-swayyourcmc.ru/git/vitalif/VMXTemplate/raw/master/VMX%2FCommon.pm VMX/Common.pm].** Исходный код грамматики PHP-версии (LALR(1) [http://yourcmc.ru/git/vitalif/lime LIME]): [http://yourcmc.ru/git/vitalif/VMXTemplate/raw/master/template.lime template.lime].** Исходный код грамматики Perl-версии (LALR(1) {{CPAN|Parse::Yapp}} Common): [http://yourcmc.ru/git/vitalif/VMXTemplate/raw/master/template.yp template.yp] и [http://yourcmc.ru/git/vitalif/VMXTemplate/raw/master/template.skel.pm template.skel.pm].** Исходный код голой грамматики (LALR(1) yacc): [http://yourcmc.ru/git/vitalif/VMXTemplate/raw/master/template.y template.y].** В Git-репозитории можно найти полную историю разработки, начиная с самых старых phpbb-подобный версий.
* Простые настройки для подсветки синтаксиса шаблонов в [http://www.midnight-commander.org/ Midnight Commander]'а: [{{SVN|vitalif/trunk/scripts/tpl.syntax|markup}} tpl.syntax]. Чтобы подсветка нормально выглядела, к tpl.syntax в начало надо дописать html.syntax из стандартного комплекта поставки mc.
=== Perl ===
[[File:Warning iconPerl версия обновлена и теперь в точности соответствует PHP-версии.svg|32px|link=]] '''Версия устарела! См. [http://www.yourcmc.ru/wiki/index.php?title=%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%82%D0%BE%D1%80_VMX::Template&oldid=6200 старую версию документации].''' {{WikiCutBegin|Всё-таки посмотреть на использование в Perl}}
<source lang="perl">
use VMX::TemplateVMXTemplate;
# Конструктор
$template = new VMX::TemplateVMXTemplate(
'root' => '.', # директория с шаблонами
'cache_dir' => undef, # директория для кэширования компилированного кода шаблонов
# если >0, то шаблоны будут перечитываться с диска не чаще чем раз в reload секунд
'print_error' => 1, # если TRUE, ошибки компиляции попадают в вывод шаблона
'log_error' => 1, # если TRUE, ошибки компиляции печатаются на STDERR
'raise_error' => 0, # если TRUE, при ошибке компиляции вызывается die()
'use_utf8' => undef, # если TRUE, использовать "use utf8" на шаблонах
'begin_code' => '<!--', # маркер начала директивы кода
'end_code' => '-->', # маркер конца директивы кода
'eat_code_line' => 1, # (похоже на TT CHOMP) съедать "лишний" перевод строки, если в строке только директива?
'begin_subst' => '{', # маркер начала подстановки выражения
'end_subst' => '}', # маркер конца подстановки выражения
'eat_code_line' => 1, # (похоже на TT CHOMP) если TRUE, съедать "лишний" перевод строки, если в строке только директива кода (begin_code..end_code)
'no_code_subst' => 1, # если TRUE, выполнять директивы кода (begin_code..end_code), но игнорировать их результат
'compiletime_functions' => # дополнительные компилируемые функции
{ 'func' => sub {} }, # хеш вида имя функции (в шаблонах) => coderef,
# которому передаются скомпилированные выражения всех аргументов и первым - сам $templateпарсер (объект VMXTemplate::Parser) 'filters' => [ sub {}, .. ], # немного legacyфильтры для запуска на выводе каждого внешнего шаблона (фильтр - функция, устаревшее:модифицирующая $_[0]) 'wrapperstrip_space' => undef0, # если coderefTRUE, через это будет пропущен вывод удалять пробелы и табы из начала и конца всех шаблонов ("глобальный фильтр")строк вывода 'strict_endauto_escape' => 0'', # требовать <!функция авто-экранирования, например "s" (для HTML- END имя_блока --> после <!-- BEGIN имя_блока -->безопасного режима)
);
# Присвоение переменных:$template->vars("ключ" { var => "значение", "ключ" => "значение"'value', ...});
# Выполнения полностью аналогичны PHP:
$template->clear;
</source>
 
{{WikiCutEnd}}
== Синтаксис шаблонов ==
Если вы знаете о порождающих грамматиках, то вот контекстно-свободная грамматика для LALR(1) алгоритма разбора:
* Голая Bison-грамматика, для получения представления о синтаксисе: {{SVN|http://yourcmc.ru/git/vitalif/trunkVMXTemplate/raw/Templatemaster/template.y|markup}}* Рабочая [httpshttp://github.com/vitalif/lime LIME]-грамматика: {{SVN|http://yourcmc.ru/git/vitalif/trunkVMXTemplate/raw/Templatemaster/template.lime|markup}} (для её работы нужен патченый LIME — см. https://github.com/vitalif/lime)* Рабочая {{CPAN|Parse::Yapp}}-грамматика: http://yourcmc.ru/git/vitalif/VMXTemplate/raw/master/template.yp
=== Пример ===
Синтаксис вызова функций:
* <tt>ФУНКЦИЯ(АРГУМЕНТ, АРГУМЕНТ, ...)</tt>
* <tt>ФУНКЦИЯ <пробел> ОДИН_АРГУМЕНТ</tt>
Существующие функции перечислены ниже. Через «=» в подзаголовках указываются синонимы функций.
Ограничение длины строки <tt>str</tt> максимальной длиной <tt>len</tt> — <tt>strlimit(str, len, dots = "...")</tt>. Если строка превышает заданную длину, она обрезается предпочтительно по пробелу или Tab’у, а в конец добавляется <tt>dots</tt> или по умолчанию <tt>"..."</tt>, если аргумент <tt>dots</tt> не передаётся.
 
==== PLURAL_RU ====
 
Выбор правильного окончания в русском языке в зависимости от количества: <tt>plural_ru(число, один, несколько, много)</tt>. Например (1 шаблон, 2-3-4-102 шаблонА, 5-6-15-… шаблонОВ):
 
<tt><nowiki>{num} шаблон{plural_ru(num, '', 'а', 'ов')}</nowiki></tt>
=== Массивы и хеши ===
== Различия PHP и Perl версий ==
 
==== Perl-версия — устаревшая ====
 
На момент 2013-04-20 Perl-версия — устаревшая. А вот актуальная для неё [http://www.yourcmc.ru/wiki/index.php?title=%D0%A8%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD%D0%B8%D0%B7%D0%B0%D1%82%D0%BE%D1%80_VMX::Template&oldid=6200 старая версия документации].
==== Кэширование работает по-разному ====
В целом, общий смысл — сделать так, чтобы шаблоны было не стыдно вызывать много раз, как много раз за один запрос, так и в целом, при этом максимально использовать механизмы интерпретатора самого языка. Но механизмы для этого применяются разные. Основная причина различий следующая:
* Perl: считается, что всё прогрессивное человечество уже давно использует <tt>mod_perl</tt> или [[Платформы для запуска Perl веб-приложений|другие способы запуска веб-приложений]], при которых частых переинициализаций интерпретатора не происходит. Иными словами, ''никто больше не использует CGI''. Таким образом, мы смело легко можем сохранить живой coderef (ссылку на функцию, или кому как больше нравится — анонимную функцию, замыкание, делегат) в промежутке между двумя запросами. Так и живём — скомпилированный шаблон представляет собой просто хеш с набором анонимных функций, которые сохраняются в my-переменной пакета VMX::Template ''экземпляре объекта VMXTemplate'' и вызываются при обращении к шаблону или его блокам. Также существует и файловый кэш компилированного кода. '''Важное следствие:''' объект VMXTemplate между запросами нужно оставлять живым. Если его убить — кэш полностью очищается.
* PHP: интерпретатор PHP всегда инициализируется заново при обработке каждого HTTP-запроса, а живой coderef в промежутке между двумя инициализациями интерпретатора сохранить, видимо, невозможно. Однако предполагается, что всё прогрессивное человечество давно использует APC/XCache/ZendOpCache/eAccelerator, и поэтому, когда текст шаблонов компилируется в файлы, а файлы подгружаются путём require, на самом деле они загружаются не с диска, а из памяти кэшера, причём — в уже скомпилированном виде. Кроме того, так как скомпилированный шаблон представляет собой класс — в рамках одного запроса он загружается максимум 1 раз, последующие вызовы происходят уже очень быстро. Ну и на всякий пожарный — хотя это, возможно, уже особого выигрыша и не даёт — нескомпилированный текст шаблонов тоже кэшируется в кэше переменных APC/XCache/eAccelerator, если таковой присутствует, и не перезагружается с диска лишний раз. Если <tt>reload = false</tt>, лишними считаются все разы, кроме первого, даже если файл шаблона менялся.
В Perl действие <tt>reload</tt> немного отличается — отличается — <tt>reload = 0</tt> работает так же, как <tt>reload = false</tt> в PHP, но если <tt>reload > 0</tt>, то тексты шаблонов всё-таки перезагружаются с диска при изменении, но не чаще, чем раз в <tt>reload</tt> секунд.
В PHP также есть ещё одна проблема — в процессе выполнения невозможно добавить метод в класс без использования извращений типа [http://pecl.php.net/package/classkit classkit], а хочется, потому что сгенерированные из кода шаблона функции должны быть методами — они дёргают разные функции от $this, подразумевая, что это объект класса VMXTemplate.
* PHP: «использовать mb_str* функции для работы со строками в выражениях».
* Perl: «я передаю в шаблон все переменные с флагом UTF-8 = On, их можно смело конкатенировать с UTF-ными частями шаблона». Если кто-то не знает, в Perl строки имеют на себе флаг UTF-8 = да или нет, и при конкатенации строки без флага со строкой с флагом строка без флага будет автоматически переведена в UTF-8 из кодировки, соответствующей текущей локали. Что означает двойное UTF-8-кодирование в случае, если строка на самом деле всё-таки в UTF-8, но просто на ней не установлен флаг.
*: Для приведения всех переменных шаблона к UTF-8 можно использовать функцию <tt>utf8on()</tt> из [{{SVN|vitaphoto/solstice/lib-sway/VMX/Common.pm}} VMX<tt>VMXTemplate::Common] Utils</tt> (рекурсивный <tt>Encode::_utf8_on()</tt>).
==== Различается способ вывода ошибок при <tt>print_error = true</tt> ====
==== Различается поведение сравнений ====
* PHP: Обычные сравнения — типозависимыеТип обычных операторов сравнения определяется во время выполнения. То есть, если во время выполнения одно из сравниваемых значений — число, они сравниваются как числа, иначе — как строки.* Perl: EQ и тТип обычных операторов сравнения определяется ''во время компиляции''. пТо есть, если из контекста понятно, что одно из сравниваемых значений — число (если это константа или результат, например, функции count), сравнение будет численным, иначе — строковым.* Пустые массивы и хеши ложны в PHP и истинны в Perl. без S/N эквивалентно строковому То есть простая проверка «IF array» (Sxxприведение к булеву типу), если array пуст, в PHP вернёт false, а в Perl — true.
==== Различается поведение некоторых функций работы с массивами и хешами ====
Это бывает весьма полезно, если нужно написать модуль к системе, которая сама написана без шаблонизатора или с каким-нибудь полу-кривым собственным, и не хочется вводить дополнительную зависимость.
[[Категория:Sway]][[Категория:РазработкаТехактивы]]
[[Категория:Perl]]
[[Категория:PHP]]

Навигация