Template Toolkit: Модули: Template::Parser

Template Toolkit

(русская редакция)

[ Пособия ] [ Руководство ] [ Модули ] [ Библиотеки ] [ Утилиты ] [ Вопросы ] [ Релиз ] [ Perl-ресурсы ] Форум ]
 
Поиск
Template Toolkit | Модули | Template::Parser

Template::Parser

[ ◄ Template::Namespace::Constants ] [ Template::Plugin ► ]
LALR(1) парсер для компиляции шаблонов.

Оглавление

ОБЗОР

Индекс ] [ Модули ] [ Наверх ]

    use Template::Parser;
    $parser   = Template::Parser->new(\%config);
    $template = $parser->parse($text)
        || die $parser->error(), "\n";

ОПИСАНИЕ

Индекс ] [ Модули ] [ Наверх ]

Модуль Template::Parser реализует LALR(1) парсер и связанные методы для разбора документов в Perl-код.

ПУБЛИЧНЫЕ МЕТОДЫ

Индекс ] [ Модули ] [ Наверх ]

new(\%params)

Конструктор 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($text)

Метод parse() разбирает текст, переданный в качестве первого аргумента и возвращает ссылку на объект Template::Document, который содержит скомпилированное представление текста шаблона. В случае ошибки возвращается undef.

Пример:

    $doc = $parser->parse($text)
	|| die $parser->error();

АВТОР

Индекс ] [ Модули ] [ Наверх ]

Энди Уардли (Andy Wardley <abw@andywardley.com>)

http://www.andywardley.com/

ВЕРСИЯ

Индекс ] [ Модули ] [ Наверх ]

2.82, поставляется в составе Template Toolkit версии 2.14, дата релиза - 4 октября 2004.

АВТОРСКИЕ ПРАВА

Индекс ] [ Модули ] [ Наверх ]

  Copyright (C) 1996-2004 Andy Wardley.  All Rights Reserved.
  Copyright (C) 1998-2002 Canon Research Centre Europe Ltd.

Этот модуль является свободно-распространяемым программным обеспечением; вы можете распространять и/или модифицировать его на тех же условиях, что и Perl.

Первоначально модуль Template::Parser был получен из отдельного парсера, сгенерированного модулем Parse::Yapp версии 0.16. Следующие замечания об авторских правах присутствуют в документации к Parse::Yapp.

Всеми правами на модуль Parse::Yapp и связанные с ним модули и скрипты владеет Францис Дизарменьен (Francois Desarmenien).

  Copyright (c) 1998 Francois Desarmenien, France. All rights reserved.

Вы можете использовать и распространять их на условиях GNU General Public License или Artistic License, как указано в файле README Perl.

СМОТРИ ТАКЖЕ

Индекс ] [ Модули ] [ Наверх ]