Как создать собственный фильтр для шаблонов Template Toolkit

Материалов по теме «Как создать собственный фильтр для шаблонов Template Toolkit» достаточно, как на русском, так и на английском языках.

А вот примеров кода реально работающего фильтра практически нет. Восполняю этот пробел, возможно кому-нибудь пригодится.

Далее изложено 3 варианта создания фильтра, все – работающие. Разъяснений и комментариев в этот раз не будет. Для изучения теории создания шаблонов рекомендую несколько публикаций, ссылки на которые приведены в заключительной части.

Варианты кода для создания фильтра

Примеры разработаны для решения задачи:
Есть строка текста неопределенной длины. Надо эту строку сократить до определенного администратором числа символов.

Вариант 1. Самый простой

1) В модуле, где происходит создание объекта шаблона, создать подпрограмму-фильтр.

Например:

$MAX_LENGTH = 30;

sub filter {
	my $text = shift;

	if (length($text) > $MAX_LENGTH) {
		...
		# обработка переменной $text регулярными выражениями,
		# формирование ее нового значения
		...
	}
	return $text;
}

Фильтр, в данном случае, выполняет следующие действия: принимает данные для обработки, проводит обработку, возвращает измененные данные. В общем, это самая обыкновенная функция.

Кстати, можно разместить фильтр в другом модуле, а потом его просто подключить с помощью use.

2) В опции, которые задаются при создании объекта TemplateToolkit, добавляем параметр FILTERS.

Пример:

...
	my $template_options = {
		...
		INCLUDE_PATH 	=> $templ_path,
		FILTERS => {
			'new_filter'  => \&filter,
		},
		...
	};

	my $template = Template->new($template_options) || do {
		$ERROR = "Can't create Template object: ".$Template::ERROR;
		return undef;
	};
...

3) Фильтр создан и его можно использовать в шаблонах Template Toolkit, как любой другой фильтр:

[%- 'очень_длинная_фраза_которую_надо_укоротить' | new_filter -%]

Вариант 2

Создаем фильтр в виде подключаемого в шаблонах плагина.

1) Создаем плагин.


package Template_Plugin::MyNewFilter;

use Template::Plugin::Filter;

use base qw( Template::Plugin::Filter );

use vars qw(
	$FIRST_PART_LENGTH
	$LAST_PART_LENGTH
	$MAX_LENGTH
);

$FIRST_PART_LENGTH = 15;
$LAST_PART_LENGTH = 7;
$MAX_LENGTH = 30;

sub filter {
	my ($self, $text) = @_;

	if (length($text) > $MAX_LENGTH) {
		$text =~ /^(.{$FIRST_PART_LENGTH}).+(.{$LAST_PART_LENGTH})$/i;
		$text = $1.'...'.$2;
	}
	return $text;
}

1;

2) Плагин-фильтр должен располагаться пространстве имен, которое задается опциями, при создании объектов Template Toolkit.

...
	my $template_options = {
		...
		PLUGIN_BASE 	=> $TTPluginBase,
		...
	};
	my $template = Template->new($template_options) ||
		do {$ERROR = "Can't create Template object:
		".$Template::ERROR; return undef;};
...

3) Используем получившийся плагин в шаблонах Template Toolkit.


[%- USE MyNewFilter -%]

[% FILTER $MyNewFilter %]очень_длинное_название_продукта_
которое_не_помещается_в_одной_строке[% END %]

Вариант 3. Самый правильный

Не знаю, как Вам, но мне не нравится указывать в шаблонах фильтр, с помощью знака доллара: FILTER $MyNewFilter . Если уж добавлять фильтр, как плагин, то и использовать, как обычный стандартный
фильтр: FILTER MyNewFilter.

Поэтому, продолжаем поиски. И находим третий вариант создания фильтра.

1) Создаем модуль плагина-фильтра:

package Template_Plugin::MyNewFilter;

use strict;
use Template::Plugin::Filter;
use base qw( Template::Plugin::Filter );

use vars qw(
	$FIRST_PART_LENGTH
	$LAST_PART_LENGTH
	$MAX_LENGTH
);

$FIRST_PART_LENGTH = 15;
$LAST_PART_LENGTH = 5;
$MAX_LENGTH = 30;

sub new {
	my ($class, $context, @params) = @_;

	my $self = {
		_CONTEXT => $context,
		_DYNAMIC => 1,
	};
       	bless $self, $class;
	$self->install_filter('MyNewFilter');

	return $self;
}

sub filter {
	my ($self, $text) = @_;

	if (length($text) > $MAX_LENGTH) {
		$text =~ /^(.{$FIRST_PART_LENGTH}).+(.{$LAST_PART_LENGTH})$/i;
		$text = $1.'...'.$2;
	}

	return $text;
}

1;

Стоит отметить, что метод install_filter предлагают использовать многие руководства по Template::Plugin::Filter, однако ни одно из них даже словом не упоминает, что необходимо создавать метод new, а так же – как его создавать. А без new стабильно работать будет только 500-ая ошибка сервера.

2) Не забываем, что плагин-фильтр должен быть размещен в определенном опцией PLUGIN_BASE пространстве имен.

3) Вот оно счастье – красивое использование фильтра:

[%- USE MyNewFilter -%]
[%- 'это-название-ни-в-какие-рамки-не-лезет' FILTER MyNewFilter -%]
или
[%- 'это-название-ни-в-какие-рамки-не-лезет' | MyNewFilter -%]

Полезные ссылки

Разнообразные теоретические аспекты создания фильтров можно узнать по приведенным ниже адресам:

http://www.template-toolkit.ru/Modules/Template/Plugin/Filter.html

http://www.template-toolkit.ru/Modules/Template/Plugin.html

http://search.cpan.org/~abw/Template-Toolkit-2.22/lib/Template/Plugin/Filter.pm

Книга: Perl Template Toolkit – O’Reilly – By Darren Chamberlain, David Cross, Andy Wardley

Комментариев нет

Комментариев нет.

RSS-лента комментариев к этой записи.

Оставить комментарий

You must be logged in to post a comment.