Конструктор new() создает и возвращает ссылку на новый объект
Template::Parser. В качестве аргумента можно передать ссылку на
со следующими опциями конфигурации:
- START_TAG, END_TAG
Опции START_TAG и END_TAG используются для определения последовательностей
символов или регулярных выражений, которые будут отмечать начало и конец
директивы шаблона. Значения по умолчанию для START_TAG и END_TAG
'[%' и '%]' соответственно, дают
знакомый стиль директив:
[% example %]
Можно использовать любые метасимволы регулярных выражений Perl, поэтому
их нужно экранировать (или использовать perl-функцию 'quotemeta'
),
если они представляют литеральные символы.
my $parser = Template::Parser->new({
START_TAG => quotemeta('<+'),
END_TAG => quotemeta('+>'),
});
Например:
<+ INCLUDE foobar +>
Можно также использовать директиву TAGS, чтобы определить
значения START_TAG и END_TAG локально внутри шаблона.
[% TAGS <+ +> %]
- TAG_STYLE
Опцию TAG_STYLE можно использовать для установки как START_TAG, так
и END_TAG в соответствие с предопределенным стилем тегов.
my $parser = Template::Parser->new({
TAG_STYLE => 'star',
});
Доступны следующие стили:
template [% ... %] (по умолчанию)
template1 [% ... %] или %% ... %% (TT версии 1)
metatext %% ... %% (Text::MetaText)
star [* ... *] (TT альтернативный)
php <? ... ?> (PHP)
asp <% ... %> (ASP)
mason <% ... > (HTML::Mason)
html <!-- ... --> (HTML комментарий)
Любые установленные значения для START_TAG и/или END_TAG переопределят
определенные с помощью TAG_STYLE.
Директиву TAGS также можно использовать для установки TAG_STYLE
[% TAGS html %]
<!-- INCLUDE header -->
- PRE_CHOMP, POST_CHOMP
Все что находится вне тегов директив рассматривается как обычный
текст и, в общем случае, пропускается без изменений (исключения
описываются в описании опции INTERPOLATE). Этот текст содержит все
пробельные символы и символы переноса строки окружающие теги директив.
Директивы, которые ничего не выводят, будут оставлять дыры в
результирующем документе.
Пример:
Foo
[% a = 10 %]
Bar
Вывод:
Foo
Bar
Опции PRE_CHOMP и POST_CHOMP могут помочь в удалении этих ненужных
пустот. Обе опции выключены по умолчанию.
my $parser = Template::Parser->new({
PRE_CHOMP => 1,
POST_CHOMP => 1,
});
Если PRE_CHOMP установлена в 1, символ новой строки и пробельные
символы, предшествующие директиве от начала строки, будут удалены.
Это равносильно подклеиванию строки, начинаемой директивой, к концу
предыдущей строки.
Foo <----------.
|
,---(PRE_CHOMP)----'
|
`-- [% a = 10 %] --.
|
,---(POST_CHOMP)---'
|
`-> Bar
Если POST_CHOMP установлена в 1, все пустое пространство после
директивы до символа новой строки включительно будет удалено.
Это равносильно включением строки, завершаемой директивой, в
начало следующей строки.
Если PRE_CHOMP или POST_CHOMP установлены в 2, вместо удаления все
пустоты сжимаются в единственный пробел. Это полезно для HTML, в
котором (как правило) блок смежных пробельных символов интерпретируется
как единичный пробел.
Вы можете использовать константы CHOMP_NONE, CHOMP_ALL и CHOMP_COLLAPSE
из модуля Template::Constants для, соответственно, выключения обрезания,
удаления всех пустот или сжатия пустот в пробел.
PRE_CHOMP и POST_CHOMP можно активировать для директив индивидуально,
помещая символ '-' в начале и/или конце директивы.
[% FOREACH user = userlist %]
[%- user -%]
[% END %]
Символы '-' активируют как PRE_CHOMP так и POST_CHOMP для одной директивы
'[%- name -%]'. Таким образом, шаблон будет
обработан как, если бы блок был записан в таком виде:
[% FOREACH user = userlist %][% user %][% END %]
Учтите, что это аналогично установке PRE_CHOMP и POST_CHOMP в
CHOMP_ALL; единственный способ добиться поведения CHOMP_COLLAPSE -
это соответствующая установка PRE_CHOMP или POST_CHOMP.
Если же PRE_CHOMP или POST_CHOMP уже установлены в CHOMP_COLLAPSE,
использование '-' даст эффект CHOMP_COLLAPSE, а не CHOMP_ALL.
Аналогично символы '+' можно использовать, чтобы запретить
опции PRE_CHOMP или POST_CHOMP (т.е. не удалять пустоты/переносы
строк) на уровне директивы.
[% FOREACH user = userlist %]
User: [% user +%]
[% END %]
Если POST_CHOMP разрешена, приведенный выше пример будет обработан,
как если бы блок был записан так:
[% FOREACH user = userlist %]User: [% user %]
[% END %]
- INTERPOLATE
Установка флага INTERPOLATE в любое истинное значение приведет к тому,
что все ссылки на переменные в тексте, (то есть находящиеся не внутри
директив, определяемых START_TAG и END_TAG) будут распознаны и
соответствующим образом обработаны.
my $parser = Template::Parser->new({
INTERPOLATE => 1,
});
В качестве признака переменной используется префикс '$'. При необходимости
можно использовать фигурные скобки (в знакомом Perl/shell стиле) для явного
выделения имен переменных.
# INTERPOLATE => 0
<a href="http://[% server %]/[% help %]">
<img src="[% images %]/help.gif"></a>
[% myorg.name %]
# INTERPOLATE => 1
<a href="http://$server/$help">
<img src="$images/help.gif"></a>
$myorg.name
# явное указание с помощью { }
<img src="$images/${icon.next}.gif">
Учитывайте ограничение, накладываемое обработчиком регулярных
выражений Perl, на максимальный размер обрабатываемого шаблона -
около 32 килобайтов или, возможно, меньше. Работа с файлами, которые
превышают этот размер обычно приводят к аварийному завершению Perl с
ошибкой сегментации. Если вы постоянно обрабатываете шаблоны такого
размера, то вам необходимо либо запретить INTERPOLATE либо разбить
шаблоны на более мелкие файлы или блоки, которые затем можно будет
собрать обратно с помощью PROCESS или INCLUDE.
- ANYCASE
По умолчанию, ключевые слова директив должны записываться в
ВЕРХНЕМ РЕГИСТРЕ. Установка опции ANYCASE разрешает использование
ключевых слов в любом регистре.
# ANYCASE => 0 (default)
[% INCLUDE foobar %] # OK
[% include foobar %] # ошибка
[% include = 10 %] # OK, 'include' - переменная
# ANYCASE => 1
[% INCLUDE foobar %] # OK
[% include foobar %] # OK
[% include = 10 %] # ошибка, 'include' - зарезервированное слово
Один из побочных эффектов разрешения ANYCASE - невозможность
использования переменных с именами из набора зарезервированных
слов вне зависимости от регистра. В настоящий момент зарезервированы
следующие слова:
GET CALL SET DEFAULT INSERT INCLUDE PROCESS WRAPPER
IF UNLESS ELSE ELSIF FOR FOREACH WHILE SWITCH CASE
USE PLUGIN FILTER MACRO PERL RAWPERL BLOCK META
TRY THROW CATCH FINAL NEXT LAST BREAK RETURN STOP
CLEAR TO STEP AND OR NOT MOD DIV END
Единственные зарезервированные слова в нижнем регистре, которые
нельзя использовать в качестве имен переменных вне зависимости от
установки ANYCASE, это операторы:
and or not mod div
- V1DOLLAR
В версии 1 Template Toolkit, перед любой переменной шаблона
можно было поставить необязательный символ '$' и он просто
игнорировался.
# ВЕРСИЯ 1
[% $foo %] === [% foo %]
[% $hash.$key %] === [% hash.key %]
Для вычисления значения переменной использовалась конструкция
'${' ... '}'. Обычно это использовалось для получения
значения хеша по ключу, сохраненному в переменной.
Например:
my $vars = {
users => {
aba => { name => 'Alan Aardvark', ... },
abw => { name => 'Andy Wardley', ... },
...
},
uid => 'aba',
...
};
$template->process('user/home.html', $vars)
|| die $template->error(), "\n";
'user/home.html':
[% user = users.${uid} %] # users.aba
Name: [% user.name %] # Alan Aardvark
Это порождало несовместимость со строками, заключенными
в двойные кавычки, а также режимом INTERPOLATE, в котором
символа '$' в тексте достаточно для выделения переменной,
которую необходимо вычислить, а дополнительные фигурные
скобки используются для явного выделения имени переменной
при необходимости. Отметим, что такое использование, помимо
прочего, согласуется с соглашениями, существующими в UNIX и
Perl.
# интерполяция внутри строки в двойных кавычках
[% name = "$title ${user.name}" %]
# INTERPOLATE = 1
<img src="$images/help.gif"></a>
<img src="$images/${icon.next}.gif">
В версии 2, эти несовместимости были устранены и синтаксис стал
более ясным. '$', предшествующий имени переменной сейчас однозначно
указывает на то, что имя переменной перед использованием должно быть
интерполировано (т.е. вычислено и заменено на значение переменной).
Приведенный раньше пример из версии 1:
# ВЕРСИЯ 1
[% user = users.${uid} %]
Name: [% user.name %]
в версии 2 может быть упрощен следующим образом:
# ВЕРСИЯ 2
[% user = users.$uid %]
Name: [% user.name %]
Предшествующий знак доллара больше не игнорируется и так же
означает интерполяцию, как и комбинация '${' ... '}'
в версии 1. Фигурные скобки по прежнему можно использовать при
необходимости для явного указания имени интерполируемой переменной.
Например:
[% user = users.${me.id} %]
Name: [% user.name %]
Это правило применяется ко всем переменным, как внутри директив, так и
в тексте при обработке с установленной опцией INTERPOLATE. Это означает
вам не следует (если вы так раньше делали) добавлять предшествующий
'$' к переменной внутри директивы, если только вы точно не хотите,
чтобы она была интерполирована.
Один очевидный побочный эффект заключается в том, что шаблоны
версии 1 с переменными, которым предшествует '$', не будут
обрабатываться как ожидается. Имея следующие определения
переменных,
[% foo = 'bar'
bar = 'baz'
%]
в версии 1 мы получим следующую интерпретацию:
# ВЕРСИЯ 1
[% $foo %] => [% GET foo %] => bar
в то время как версия 2 интерпретирует это так:
# ВЕРСИЯ 2
[% $foo %] => [% GET $foo %] => [% GET bar %] => baz
В версии 1, '$' игнорировался - мы получали и выводили значение
переменной 'foo'. В версии 2, переменная '$foo' вначале вычисляется
и получается имя переменной 'bar', значение которой затем выводится.
Использование дополнительного '$' не рекомендовалось, но для обеспечения
обратной совместимости с шаблонами версии 1, которые могут зависеть от
этой "возможности", можно установить опцию V1DOLLAR в 1 (по умолчанию: 0),
чтобы вернуть прежнее поведение и игнорировать предшествующие символы '$'.
my $parser = Template::Parser->new({
V1DOLLAR => 1,
});
- GRAMMAR
Элемент конфигурации GRAMMAR используется для определения альтернативной
грамматики для парсера. Это позволяет сконструировать и использовать в
Template Toolkit измененный или совершенно новый язык шаблонов.
Исходные шаблоны компилируются в perl-код объектом Template::Parser,
использующим по умолчанию Template::Grammar для определения структуры
и семантики языка. Таким образом, скомпилированные шаблоны по сути
"совместимы" друг с другом и нет ничего, что могло бы помешать
компилировать и использовать шаблоны, использующих любое количество
языков, в рамках одного и того же окружения обработки данных
Template Toolkit (кроме обычных ограничений по времени и памяти).
Файл Template::Grammar собирается из файла грамматики YACC (с
использованием Parse::YAPP) и скелетного шаблона модуля. Эти файлы
вместе с маленьким скриптом для перестройки грамматики поставляются
в составе пакета в подкаталоге 'parser'. Вам не нужно ничего знать
и беспокоится об этом, если только вы не хотите подправить язык шаблонов
или создать свой собственный вариант. В этом же каталоге находится
файл README с небольшой инструкцией, но подразумевается, что вы знаете,
что делаете, если рискнете заняться этим. Если вы знаток парсеров
LALR, это не вызовет у вас затруднений.
Экземпляр Template::Grammar по умолчанию будет создан и использован
автоматически, если элемент GRAMMAR не определен.
use MyOrg::Template::Grammar;
my $parser = Template::Parser->new({
GRAMMAR = MyOrg::Template::Grammar->new();
});
- DEBUG
Опция DEBUG используется для включения отладочной диагностики
в модуле Template::Parser.
use Template::Constants qw( :debug );
my $template = Template->new({
DEBUG => DEBUG_PARSER | DEBUG_DIRS,
});
Значение DEBUG может содержащее любое из приведенных. Несколько
значений можно совместить с помощью логического оператора OR, '|'.
- DEBUG_PARSER
Этот флаг вынуждает Template::Parserгенерировать отладочные сообщения, которые показывают сгенерированный
в ходе разбора и компиляции каждого шаблона perl-код.
- DEBUG_DIRS
Эта опция вынуждает Template Toolkit генерировать комментарии,
содержащие имя файла, строку и оригинальный текст каждой директивы
шаблона. Эти комментарии включаются в вывод шаблона с использованием
шаблона, определенного в опции конфигурации DEBUG_FORMAT, либо с
использованием простого формата по умолчанию, если эта опция не
определена.
Например, следующий фрагмент шаблона:
Hello World
сгенерирует следующий вывод:
## input text line 1 : ##
Hello
## input text line 2 : World ##
World
Метод parse() разбирает текст, переданный в качестве первого
аргумента и возвращает ссылку на объект Template::Document,
который содержит скомпилированное представление текста шаблона.
В случае ошибки возвращается undef.