Главная страница статей --> Хитрости при программировании php, заметки по базам данных

Генерация контента сайта с использованием Template Toolkit

Источник: realcoding.net

[2 страница]

ДИНАМИЧЕСКАЯ ГЕНЕРАЦИЯ СТРАНИЦ ЧЕРЕЗ ОБРАБОТЧИК APACHE/MOD_PERL



ВНИМАНИЕ: Вы можете скачать из сети CPAN модуль Apache::Template, который обеспечивает простой и легкий в использовании интерфейс между Apache/mod_perl и Template Toolkit. В момент написания этого документа был доступен первый релиз (0.01), который предлагает только самые базовые возможности, но в нем реализована большая часть, если не все, что описано ниже. Следует избегать необходимости писать свой собственный обработчик. Тем не менее, во многих случаях, вам может понадобиться написать свой собственный обработчик под ваши собственные нужды, и этот раздел покажет вам с чего начинать.


Модуль Template можно использовать обычным способом из обработчика Apache/mod_perl. Ниже приведен типичный фрагмент файла конфигурации Apache httpd.conf:

PerlModule CGI;

PerlModule Template

PerlModule MyOrg
::Apache::User


PerlSetVar websrc_root
/home/abw/websrc


<Location /user/bin>

SetHandler perl-script

PerlHandler MyOrg
::Apache::User

</Location>

Этот фрагмент определяет URL /user/bin, все запросы к которому будут передаваться методу handler() модуля MyOrg::Apache::User. Этот модуль может выглядеть приблизительно так:

package MyOrg::Apache::User;


use
strict;

use
vars qw( $VERSION );

use
Apache::Constants qw( :common );

use
Template qw( :template );

use
CGI;


$VERSION = 1.59;


sub handler {

my $r = shift;


my $websrc = $r->dir_config(websrc_root)

or return
fail($r, SERVER_ERROR,

websrc_root not specified);


my $template = Template->new({

INCLUDE_PATH => $websrc/src/user:$websrc/lib,

PRE_PROCESS => config,

OUTPUT => $r, # прямой вывод в объект запроса Apache

});


my $params = {

uri => $r->uri,

cgi => CGI->new,

};


# используем path_info для определения шаблона, который необходимо обработать

my $file = $r->path_info;

$file =~ s[^/][];


$r->content_type(text/html);

$r->send_http_header;


$template->process($file, $params)

return
fail($r, SERVER_ERROR, $template->error());


return
OK;

}


sub fail {

my ($r, $status, $message) = @_;

$r->log_reason($message, $r->filename);

return
$status;

}

Обработчик получает в качестве параметра запрос и использует его для определения значения websrc_root из файла конфигурации. Это значение затем используется для определения INCLUDE_PATH при создании объекта Template. Далее из запроса получаем URI и создаем объект CGI. Оба объекта определяются как переменные шаблона.


Само имя шаблона извлекается из PATH_INFO запроса. В нашем примере, оно будет частью URL, идущего после /user/bin, то есть для /user/bin/edit, шаблоном будет файл edit, расположенный в "$websrc/src/user" Далее выводим заголовки и обрабатываем шаблон. Весь вывод отправляется напрямую в метод print() объекта запроса Apache.

ИСПОЛЬЗОВАНИЕ МОДУЛЕЙ-РАСШИРЕНИЙ (ПЛАГИНОВ)



Как мы уже показали, при создании динамического контента с помощью CGI скриптов или обработчиков Apache/mod_perl можно связывать данные и функции из Perl с переменными шаблона. Template Toolkit также предоставляет интерфейс для создания модулей расширений (плагинов), который позволяет вам определить эти дополнительные данные и/или функциональность в отдельном модуле и затем загрузить его и использовать по назначению с помощью директивы USE.


Основное преимущество такого подхода заключается в том, что вы можете использовать такое расширение в любых шаблонах, даже в тех, которые используются при построении статического контента с помощью tpage или ttree. Вам не нужно специально писать обертку на Perl только для того, чтобы загрузить модуль и сделать его доступным через хэш переменных шаблона.


Давайте продемонстрируем этот принцип на примере плагина DBI, написанного Симоном Мэттьюсом (Simon Matthews <sam@knowledgepool.com>). Вы можете создать этот шаблон в вашем каталоге src, обработать его при помощи ttree и посмотреть результат. Разумеется, этот пример зависит от наличия подходящей базы данных SQL, но вы можете адаптировать его под ваши возможности, либо просто рассматривать как пример возможностей Template Toolkit.

[% INCLUDE header

title
= User Info

%]


[% USE
DBI(dbi:mSQL:mydbname) %]


<
table border=0 width=100%>

<
tr>

<
th>User ID</th>

<
th>Name</th>

<
th>Email</th>

</
tr>


[% FOREACH
user = DBI.query(SELECT * FROM user ORDER BY id) %]

<
tr>

<
td>[% user.id %]</td>

<
td>[% user.name %]</td>

<
td>[% user.email %]</td>

</
tr>

[%
END %]


</
table>


[% INCLUDE
footer %]

Плагин - это обычный Perl модуль, расположенный в определенном месте и согласующийся с известными стандартами таким образом, чтобы Template Toolkit смог найти его и автоматически загрузить. Вы можете создать свой собственный плагин с помощью наследования модуля Template::Plugin.


Ниже приведен пример, который определяет некоторые данные (foo и people) и также метод объекта (bar). За неимением лучшего мы назовем плагин FooBar и создадим его в пакете MyOrg::Template::Plugin::FooBar. Мы добавили MyOrg к обычному имени пакета Template::Plugin::*, чтобы избежать конфликта имен с существующими плагинами.


Заготовку модуля можно сделать с помощью Perl утилиты h2xs:

h2xs -A -X -n MyOrg::Template::Plugin::FooBar

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

package MyOrg::Template::Plugin::FooBar;


use
Template::Plugin;

use
vars qw( $VERSION );

use
base qw( Template::Plugin );


$VERSION = 1.23;


sub new {

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


bless {

_CONTEXT => $context,

foo => 25,

people => [ tom, dick, harry ],

},
$class;

}


sub bar {

my ($self, @params) = @_;

# ...что-то делает...

return $some_value;

}

Как принято в Perl, конструктор плагина new() получает имя класса в качестве первого параметра. Следующий параметр - ссылка на экземпляр объекта Template::Context. Сейчас вам не нужно беспокоится об этом объекте. Это основной объект парсера Template Toolkit. Он предоставляет доступ к функциональности процессора и некоторым плагинам может понадобится взаимодествовать с ним. Нам это пока не нужно, но мы тем не менее сохраним эту ссылку в переменной объекта _CONTEXT. Начальное подчеркивание - это соглашение об именах переменных, которое указывает что эта переменная приватная и Template Toolkit не будет пытаться получить доступ к этой переменной. Другие определяемые переменные foo и people - это обычные данные, которые будут доступны из шаблонов, использующих этот плагин. Следом за ссылкой на объект Template::Context идут дополнительные параметры, которые указываются с директивой USE, такие как источник данных, dbi:mSQL:mydbname, который мы использовали в предыдущем примере с плагином DBI.


Если для создания заготовки модуля вы использовали h2xs, то у вас уже есть файл Makefile.PL и вы можете выполнить знакомую процедуру по сборке и установке модуля. Не забудьте добавить тесты в test.pl!

perl Makefile.PL

make

make test

make install

Если вы не стали или не смогли установить плагин в обычное место для хранения модулей Perl (например, если у вас недостаточно привилегий), вы можете установить переменную окружения PERL5LIB, чтобы указать другое место, где установлен модуль. Если вы используете ttree, вместо этого вы можете добавить следующую строку в ваш конфигурационный файл. Это будет равносильно добавлению /path/to/modules в массив @INC.

$HOME/.ttreerc:


perl5lib = /path/to/modules

Еще одна дополнительная строка должна быть добавлена, чтобы указать парсеру новое имя пакетов, которое мы создали для наших плагинов:

$HOME/.ttreerc:


plugin_base = MyOrg::Template::Plugin

Если вы пишите скрипт, использующий модуль Template напрямую, эта переменная может быть передана как параметр конфигурации при создании объекта.

use Template;


my $template = Template->new({

PLUGIN_BASE => MyOrg::Template::Plugin

});

Теперь мы можем создать шаблон, использующий этот плагин:

[% INCLUDE header

title
= FooBar Plugin Test

%]


[% USE
FooBar %]

Some values available from this plugin:

[% FooBar.foo %] [% FooBar.bar %]


The users defined in the people list:

[% FOREACH
uid = FooBar.people %]

* [%
uid %]

[%
END %]


[% INCLUDE
footer %]

Члены foo, bar и people из плагина FooBar автоматически преобразуются в соответствующие переменные или вызовы методов лежащего в основе объекта.


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

Контакты
Редакция:
[0.001]