Template::EasyTT
Модуль для разбора шаблонов.
$tmpl = Template::EasyTT->new({
INCLUDE_PATH => undef,
SECURE_INC => 0,
INCLUDE => 1,
FOREACH => 1,
GLOBAL_IF => 1,
LOCAL_IF => 1,
STOP => 1,
LOCK_OK => 1,
DEBUG => 0,
REPLACEMENT => 0,
FILTERS => {},
OPERATORS => {},
PARENT => bless {}
});
$tmpl->process( $file, $ptr, $handle );
$tmpl = Template::EasyTT->new({ ОПЦИИ });
ОПЦИИ:
Путь откуда по умолчанию вставляются файлы для INCLUDE, если не определено то директория таже из которой вызван основной шаблон. [ undef ]
Если 1 - то в INCLUDE имя файла очищается от ../ и пр... Т.е. что то типа basename. [ 0 ]
Если 1 - то разрешена отработка комманд INCLUDE [ 1 ]
Если 1 - то разрешена отработка комманд FOREACH [ 1 ]
Если 1 - то разрешена отработка комманд STOP [ 1 ]
Если 1 - то разрешена отработка комманд IF ( первый проход отлавливает только ифы с глобальными переменными, те которые могут появится в результате разбора FOREACH игнорируются ) [ 1 ]
Если 1 - то разрешена отработка комманд IF ( второй проход ) [ 1 ]
Если 1 - то разрешить при открытии шаблона лочить его. [ 1 ]
Ссылка на хеш. Ключи имена фильтров, значения ссылки на процедуры обработки этих фильтров.
Ссылка на хеш. Ключи имена операторов, значения ссылки на процедуры обработки этих операторов.
Ну это указатель на блеснутый обьект, используется например если в нем определена процедура print то с помощью нее все и печатается...
Уровень отладки. Побитовый флаг принимает следующие значения:
Разобрать шаблон только до определенного этапа, и вернуть необработанные данные. Т.е. например можно циклы IF и FOREACH обработать заранее, а потом делать только замену самих контейнеров, иногда быстрее получается... Место до которого производится обработка исходного шаблона определяется флагами. Флаги такие же как и у DEBUG, с тем различием, что флаги нельзя группировать. Т.е. REPLACEMENT => 0x08 обработать GLOBAL_IF, FOREACH, INCLUDE, LOCAL_IF и отдать полученный результат...
Обрабатывает шаблоны.
- $file - имя файла шаблона. Вместо имени файла
может быть указатель на скаляр с текстом
шаблона, в этом случае автоматически
запрещается выполнение директивы `INCLUDE'
- $ptr - указатель на хеш с контейнерами
- $handle - ссылка или на скаляр или глоб в которые пишем
отпарсеный шаблон.
Если все OK то возвращает 1. Иначе рекомендуется проверить переменную $Template::EasyTT::ERROR
Производит фильтрацию данных.
- $filter_name - имя фильтра
- $data - данные которые надо пропустить через фильтр
Возвращает отфильтрованные данные.
Добавляет новый фильтр.
- $filter_name - имя фильтра
- $code_href - ссылка на процедуру обработки фильтра.
Возвращает имя фильтра. Если вызвать без аргументов то возвращает массив имен фильтров.
Добавляет новый оператор для использования в конструкциях IF UNLESS ELSIF...
- $op_name - имя оператора
- $code_href - ссылка на процедуру обработки оператора.
В процедуру передаются два значения для сравнивания. Процедура должна возвращать TRUE || FALSE
Возвращает имя оператора. Если вызвать без аргументов то возвращает массив имен операторов.
Если определено $new_value то устанавливает новое значение
переменной $options ( IF, LOCK_OK, ... ).
В любом случае возвращает текущее (/новое) состояние опции $option.
Понимает примерно следующие конструкции:
[% IF VAR %]...[% ELSIF VAR %]...[% ELSE %]...[% END %]
[% IF VAR > '12' %]...[% ELSIF VAR %]...[% ELSE %]...[% END %]
[% IF VAR ne VAR2 %]...[% ELSIF VAR3 contain VAR %]...[% ELSE %]...[% END %]
[% UNLESS VAR %]...[% ELSIF VAR ne 'tra ta ta' %]...[% ELSE %]...[% END %]
[% INCLUDE file_name %] [% INCLUDE file_name | filter1 | filter2 %]
[% FOREACH VAL = ARRAY_REF %]...[% END %]
[% ANY_PATTERN [| filter ] %]
[% ANY_PATTERN.key [| filter] %] ( hash ref )
[% ANY_PATTERN.index [| filter] %] ( array ref )
[% ANY_PATTERN.index.index2 [| filter | filter2 ] %] ( array of array ref )
[% STOP %]
- В шаблонах понимаются ссылки A.B.C может означать следующее например: $A->{B}->{C} или $a->[B]->{C} в зависимости от контекста...
- Если непосредственно после контейнера стоит \n то он обрубается... Хотя щас '\n' после обычных контейнеров не режется. Т.е. у [% MY_VAR %] - '\n' не удаляется, а например у [% IF a > B %] - удаляется...
- При использовании IF ... если аргумент ( только второй ) находится в кавычках то он считается константой ( [% IF A eq 'B' %] ), если без кавычек то переменной переданной в шаблон ( [% IF A > B %] )...
- Внутри контейнера в именах переменных и фильтров желательно пользовать [A-Za-z0-9_].
- Порядок разбора шаблона:
1 - Парсятся IF циклы ( глобальные ).
2 - Заменяются INCLUDE.
4 - Обрабатываются циклы FOREACH
2 - Парсятся IF циклы ( которые могли
образоваться после FOREACH и INCLUDE ).
3 - Обрабатывается [% STOP %] если есть.
5 - Обрабатываются все [% * %] контейнеры.
- Внутри контейнера в качестве пробельных символов используются только 'пробел' и 'таб'
- Внутри строк можно пользовать %xx. где xx - шестнадцатиричное число, которым представлен символ...
- Для комментария контейнера используйте: [%\ TEST %]
- В процедуры обработки шаблонов и операторов первым параметром передается обьект созданный Template::EasyTT->new();
- А вообще мне нужно было шустрое средство к которому можно легко прикрутить новых фильтров и логических операторов, и чтобы доступ к этим шаблонам можно было разрешить посторонним людям...
- В переменной $Template::EasyTT::MAX_SLICE лежит значение, влияющее на
максимальное количество обрабатываемых контейнеров. Ну эта ручка сделана,
чтобы при split'е не создать `случайно' массив скажем длинной несколько
сотен тысяч элементов, а так в цикле отрабатываем по
$MAX_SLICE элементов. Эта переменная влияет только на
_ОБЫЧНЫЕ_ контейнеры, к циклам она не относится. По умолчанию
$MAX_SLICE = 10000.
При использовании под Win32 и указании в качестве пути к шаблону имя распаренной директории ( т.е. '\\SERVER\dir\sub_dir\...' ) файл не найдется, это связано с тем, что File::Spec::Win32 не может корректно распарсить такой путь. Как вариант решения - открывайте такие файлы сами, читайте и передавайте в process вместо имени файла ссылку на SCALAR в котором находится прочитанный файл. В этом случае правда становится невозможным использование INCLUDE, это сделано совершенно осознанно...
При использовании синтаксиса вида [% A.B.C %], если A - указатель на хеш и B ключ хеша, имеющий символы отличные от [0-9A-Za-z_] ( или с натяжкой равные [|\s%\]] ) то возможны ( или неизбежны ) глюки, в виду особенности разбора тегов...
Более детально показано в примерах...
Okunev Igor V. mailto:igor@prv.mts-nn.ru
http://www.mts-nn.ru/~gosha