Repository URL to install this package:
|
Version:
3.0.4 ▾
|
<?xml version="1.0" encoding="koi8-r" ?>
<!--
Source: http://forum.template-toolkit.ru/rss/forum_8.rss
Expect: KOI8-R
-->
<rss version='2.0'>
<channel>
<title>Форумы Template Toolkit : Библиотеки для работы с шаблонами в Perl</title>
<link>http://forum.template-toolkit.ru/view_forum/forum_id-8.html?rss</link>
<description>Template Toolkit - быстрая, мощная и расширяемая система обработки шаблонов. На сайте работает форум, в котором обсуждаются вопросы использования библиотеки по работе с шаблонами. Text::Template, HTML::Template, Mason и другие библиотеки</description>
<language>ru</language>
<copyright>Lobanov Igor</copyright>
<webMaster>Lobanov Igor <webmaster@template-toolkit.ru></webMaster>
<pubDate>Thu, 17 Mar 2005 12:03:32 GMT</pubDate>
<lastBuildDate>Wed, 4 Jan 2006 02:29:01 GMT</lastBuildDate>
<managingEditor>Perl script, Template Toolkit</managingEditor>
<image>
<url>http://forum.template-toolkit.ru/images/tt2powered.gif</url>
<title>Template Toolkit - шаблоны в perl</title>
<link>http://forum.template-toolkit.ru/</link>
<width>88</width>
<height>31</height>
</image>
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
<item>
<guid isPermaLink="true">http://forum.template-toolkit.ru/view_topic/topic_id-53.html?rss</guid>
<pubDate>Tue, 28 Dec 2004 19:07:19 GMT</pubDate>
<title>Разделение кода, представления, и конфигурации</title>
<link>http://forum.template-toolkit.ru/view_topic/topic_id-53.html?rss</link>
<description>На <a target="_blank" href="http://www.theperlreview.com/">Perl Review</a> опубликована статья Брайана де Фоя (brian d foy) &quot;Separating Code, Presentation, and Configuration&quot;. Ниже приводится перевод статьи.<br /><br /><span style="font-weight:bold">Краткий обзор.</span><br /><br />Я взял программу из предыдущей статьи и разделил код, представление и конфигурацию, чтобы сделать программу более гибкой и легкой для поддержки.<br /><br /><span style="font-weight:bold">1. Введение.</span><br /><br />В последнем выпуске я представил программу, которую я использую для того, чтобы забирать и отображать Rich Site Summaries (RSS) с других веб-сайтов<span style="font-weight:bold"><sup>1</sup></span>. В коде я использовал литеральные величины, чтобы указать какие файлы загружать и как представлять данные, и обещал что в этом выпуске я это исправлю.<br /><br /><span style="font-style:italic">Листинг 1</span> содержит программу, которую я представлял в предыдущем выпуске. В массиве <span style="font-weight:bold">@files</span> хранятся файлы, которые необходимо загрузить, <span style="font-weight:bold">$base</span> - каталог, где сохраняется вывод, и несколько выражений <span style="font-weight:bold">print</span> создают HTML с подстановкой простых переменных (что предпочтительнее скажем чем использовать HTML-функции модуля CGI). Это негибкий и трудный для сопровождения код. Когда я захочу поменять список сайтов или вывод, я рискую сломать программу, если наберу что-то неправильно или сделаю другую ошибку.<br /><br /><span style="font-style:italic">Листинг 1: Загрузчик RSS с жесткопрописанными значениями.</span><br /><div class="code"><pre>1 #!/usr/bin/perl -w
2 use strict;
3
4 use LWP::Simple;
5 use XML::RSS;
6
7 my @files = qw(
8 http://use.perl.org/useperl.rss
9 http://search.cpan.org/rss/search.rss
10 http://jobs.perl.org/rss/standard.rss
11 http://www.perl.com/pace/perlnews.rdf
12 http://www.perlfoundation.org/perl-foundation.rdf
13 http://www.stonehenge.com/merlyn/UnixReview/ur.rss
14 http://www.stonehenge.com/merlyn/WebTechniques/wt.rss
15 http://www.stonehenge.com/merlyn/LinuxMag/lm.rss
16 );
17
18 my $base = '/usr/home/comdog/TPR/rss-html';
19
20 foreach my $url ( @files )
21 {
22 my $file = $url;
23
24 $file =~ s|.*/||;
25
26 my $result = open my $fh, &quot;&gt; $base/$file.html&quot;;
27
28 unless( $result )
29 {
30 warn &quot;Could not open [$file] for writing! $!&quot;;
31 next;
32 }
33
34 select $fh;
35
36 my $rss = XML::RSS-&gt;new();
37 my $data = get( $url );
38 $rss-&gt;parse( $data );
39
40 my $channel = $rss-&gt;{channel};
41 my $image = $rss-&gt;{image};
42
43 print &lt;&lt;&quot;HTML&quot;;
44 &lt;table cellpadding=1&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#000000&quot;&gt;
45 &lt;table cellpadding=5&gt;
46 &lt;tr&gt;&lt;td bgcolor=&quot;#aaaaaa&quot; align=&quot;center&quot;&gt;
47 HTML
48
49 if( $image-&gt;{url} )
50 {
51 my $img = qq|&lt;img src=&quot;$$image{url}&quot; alt=&quot;$$channel{title}&quot;&gt;|;
52 print qq|&lt;a href=&quot;$$channel{link}&quot;&gt;$img&lt;/a&gt;&lt;br&gt;\n|;
53 }
54 else
55 {
56 print qq|&lt;a href=&quot;$$channel{link}&quot;&gt;$$channel{title}&lt;/a&gt;&lt;br&gt;\n|;
57 }
58
59 print &lt;&lt;&quot;HTML&quot;;
60 &lt;font size=&quot;-1&quot;&gt;$$channel{description}&lt;/font&gt;
61 &lt;/td&gt;&lt;/tr&gt;
62 &lt;tr&gt;&lt;td bgcolor=&quot;#bbbbff&quot; width=200&gt;&lt;font size=&quot;-1&quot;&gt;
63 HTML
64
65 foreach my $item ( @{ $rss-&gt;{items} } )
66 {
67 print qq|&lt;b&gt;&gt;&lt;/b&gt;&lt;a href=&quot;$$item{link}&quot;&gt;$$item{title}&lt;/a&gt;&lt;br&gt;&lt;br&gt;\n|;
68 }
69
70 print &lt;&lt;&quot;HTML&quot;;
71 &lt;/font&gt;&lt;/td&gt;&lt;/tr&gt;
72 &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
73 &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
74 HTML
75
76 close $fh;
77 }</pre></div><br /><br /><span style="font-weight:bold">2. Отделение представления.</span><br /><br />Хороший дизайн не связывает себя с частным представлением данных. Моя программа должна забрать данные и сделать их доступными чему-то, что их представляет - то, что я работаю с RSS не должно иметь значения. Я могу захотеть производить HTML, TeX, простой текст, или даже какой-то формат, который не могу себе представить.<br /><br />Возможно кто-то захочет написать собственную систему для работы с шаблонами, но мне нравится модуль Text::Template Марка-Джейсона Доминуса (Mark-Jason Dominus). Он делает все что мне необходимо, не требует для своей работы дополнительных программ и написан полностью на Perl. У него простой интерфейс и мне не требуется изучать язык шаблонов, поскольку шаблоны используют Perl.<br /><br /><span style="font-style:italic">Листинг 2</span> - это та же программа, только вместо внедренного HTML используется Text::Template. В строке 5 я импортирую метод fill_in_file(). В строке 13 указываю шаблон, который буду использовать. Весь HTML, используемый программой, теперь вынесен в файл шаблона, приведенный в <span style="font-style:italic">листинге 3</span>.<br /><br />Модуль Text::Template может принимать данные как хеш. Ключи хеша становятся именами переменных в шаблоне, а значения - значениями переменных шаблона, а также определяют тип переменных. Если значение хеша простой скаляр, переменная шаблона скаляр. Если значение хеша - анонимный массив, переменная шаблона - массив, и так далее.<br /><br />Объект, создаваемый XML::RSS - анонимный хеш. Модуль предоставляет абстрактный интерфейс для создания, но не для доступа. Это отчасти именно то, что я должен передать моему шаблону. В шаблоне <span style="font-weight:bold">$rss-&gt;channel</span>, которая в качестве значения содержит анонимный хеш, становится <span style="font-weight:bold">%channel</span>, а <span style="font-weight:bold">$rss-&gt;items</span>, содержащая анонимный массив становится <span style="font-weight:bold">@items</span>.<br /><br /><span style="font-style:italic">Листинг 2: Использование шаблона.</span><br /><div class="code"><pre>1 #!/usr/bin/perl -w
2 use strict;
3
4 use LWP::Simple;
5 use Text::Template qw(fill_in_file);
6 use XML::RSS;
7
8 my @files = qw(
9 http://use.perl.org/useperl.rss
10 );
11
12 my $base = '.';
13 my $template = 'rss-html.tmpl';
14
15 foreach my $url ( @files )
16 {
17 my $file = $url;
18
19 $file =~ s|.*/||;
20
21 my $result = open my $fh, &quot;&gt; $base/$file.html&quot;;
22
23 unless( $result )
24 {
25 warn &quot;Could not open [$file] for writing! $!&quot;;
26 next;
27 }
28
29 my $rss = XML::RSS-&gt;new();
30 my $data = get( $url );
31 $rss-&gt;parse( $data );
32
33 print fill_in_file( $template, HASH =&gt; $rss );
34 close $fh;
35 }</pre></div><br /><br />Внутри шаблона Text::Template исполняет блоки кода, которые он находит между фигурными скобками. Он заменяет блок последним вычисленным выражением. Имена переменных - ключи хеша, ссылку на который я передал в качестве аргумента функции fill_in_file() в коде, приведенном в <span style="font-style:italic">листинге 2</span>.<br /><br /><span style="font-style:italic">Листинг 3: HTML шаблон.</span><br /><div class="code"><pre>1 &lt;table cellpadding=1&gt;&lt;tr&gt;&lt;td bgcolor=&quot;#000000&quot;&gt;
2 &lt;table cellpadding=5&gt;
3 &lt;tr&gt;
4 &lt;td bgcolor=&quot;#aaaaaa&quot; align=&quot;center&quot;&gt;
5 &lt;a href=&quot;{ $channel{link} }&quot;&gt;{
6
7 $image ? qq|&lt;img src=&quot;$image&quot; alt=&quot;$channel{title}&quot;&gt;| : $channel{title}
8
9 }&lt;/a&gt;&lt;br&gt;
10
11 { $channel{description} }
12 &lt;/td&gt;
13 &lt;/tr&gt;
14
15 &lt;tr&gt;
16 &lt;td bgcolor=&quot;#bbbbff&quot; width=200&gt;&lt;font size=&quot;-1&quot;&gt;
17 {
18 my $str;
19
20 foreach my $item ( @items )
21 {
22 $str .= qq|&lt;b&gt;&gt;&lt;/b&gt;&lt;a href=&quot;$$item{link}&quot;&gt;$$item{title}&lt;/a&gt;&lt;br&gt;&lt;br&gt;\n|;
23 }
24
25 $str;
26 }&lt;/font&gt;&lt;/td&gt;
27 &lt;/tr&gt;
28 &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
29 &lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</pre></div><br /><br />Как только система шаблонов задейстована, я могу менять представление не меняя логику кода. Если я приму решение изменить вид представления данных, я поменяю только шаблон. Если мне вместо HTML требуется простой текст, я только изменю под новый формат шаблон, как это сделано в <span style="font-style:italic">листинге 4</span>.<br /><br /><span style="font-style:italic">Листинг 4: Шаблон для обычного текста.</span><br /><div class="code"><pre>1 { $channel{title} }
2
3 { $channel{description} }
4
5 {
6 my $str;
7
8 foreach my $item ( @items )
9 {
10 $str .= qq|* $$item{title}\n|;
11 }
12
13 $str;
14 }</pre></div><br /><br /><span style="font-weight:bold">3. Отделение конфигурации.</span><br /><br />Хороший дизайн также позволяет адаптировать скрипт к различному окружению. В <span style="font-style:italic">листинге 1</span> я жестко прописал значение директории для вывода, что делает мой скрипт хрупким - если моя домашняя директория поменяется, скрипт сломается. Кроме того <span style="font-style:italic">в листинге 2</span> жестко прописано имя шаблона, несмотря на то что я могу менять представление, изменяя шаблон. Мне нужно иметь возможность давать каждому шаблону содержательное имя вместо использования одного и того же имени для разного содержимого.<br /><br />Многие свободно-доступные скрипты, которые я нашел в Интернет требуют, чтобы пользователь отредактировал верхнюю часть скрипта или включаемую библиотеку, которая содержит только конфигурационные данные. Такой подход требует, чтобы конечный пользователь знал основы языка программирования и правил скрипт - ошибка сломает скрипт. Плохие конфигурационные данные могут привести к неожиданным результатам, но они не поломают программу.<br /><br />Я могу указать текущие конфигурационные данные несколькими способами и покажу только один из них. Архив Comprehensive Perl Archive Network (CPAN)<span style="font-weight:bold"><sup>2</sup></span> содержит несколько модулей для разбора конфигурационных файлов в различных форматах или аргументов командной строки. Дизайнеры должны выбирать подход, который удовлетворяет их нуждам.<br /><br />Когда я впервые начал отделять данные конфигурации от моих скриптов, я перебрал несколько модулей на CPAN и остановился на ConfigReader::Simple, который использует построчный формат ключ-значение. Я использовал его настолько часто, что начал отправлять мои изменения Беку Оберину (Bek Oberin), автору оригинальной версии, затем полностью взял на себя поддержку модуля.<br /><br /><span style="font-style:italic">Листинг 5</span> адаптирует <span style="font-style:italic">листинг 2</span> к использованию ConfigReader::Simple. Я создаю новый объект конфигурации, затем читаю значения из объекта. Модуль преобразует имена ключей конфигурации в имена методов для простого доступа (хотя для доступа к значениям ключей с экзотическими именами, которые не могут быть преобразованы в идентификаторы Perl приходится использовать метод get()). <span style="font-style:italic">Листинг 6</span> содержит конфигурационный файл.<br /><br /><span style="font-style:italic">Листинг 5: Использование ConfigReader::Simple.</span><br /><div class="code"><pre>1 #!/usr/bin/perl -w
2 use strict;
3
4 use ConfigReader::Simple;
5 use LWP::Simple;
6 use Text::Template qw(fill_in_file);
7 use XML::RSS;
8
9 my $config = ConfigReader::Simple-&gt;new( './rss.config' );
10
11 my $base = $config-&gt;base;
12 my $template = $config-&gt;template;
13 my $extension = $config-&gt;extension;
14
15 my @files = split /\s+/, $config-&gt;files;
16
17 foreach my $url ( @files )
18 {
19 my $file = $url;
20
21 $file =~ s|.*/||;
22
23 my $result = open my $fh, &quot;&gt; $base/$file.$extension&quot;;
24
25 unless( $result )
26 {
27 warn &quot;Could not open [$file] for writing! $!&quot;;
28 next;
29 }
30
31 my $rss = XML::RSS-&gt;new();
32 my $data = get( $url );
33 $rss-&gt;parse( $data );
34
35 print $fh fill_in_file( $template, HASH =&gt; $rss );
36 close $fh;
37 }</pre></div><br /><span style="font-style:italic">Листинг 6: Файл конфигурации.</span><br /><div class="code"><pre>1 base .
2 template rss-html.tmpl
3 files http://use.perl.org/useperl.rss
4 extension html</pre></div><br /><br /><span style="font-weight:bold">4. Заключение.</span><br /><br />Я могу уменьшить размер моих программ, отделяя код от логики представления и конфигурационной информации. Это разделение делает программу более гибкой и простой в адаптации к новым окружениям. Шаблоны позволяют изменять вывод, а конфигурационные файлы управлять работой программы без изменения кода. Text::Template и ConfigReader::Simple делают это настолько простым, насколько возможно.<br /><br /><span style="font-weight:bold">5. Ссылки</span><br /><br />Все модули, упоминаемые в этой статье, можно найти на Comprehensive Perl Archive Network (CPAN) - <a target="_blank" href="http://search.cpan.org">http://search.cpan.org</a><br /><br /><span style="font-weight:bold">6. Об авторе.</span><br /><br />Брайан де Фой (brian d foy) - издатель <span style="font-style:italic">The Perl Review</span>.<br /><br /><span style="font-weight:bold">Примечания.</span><br /><br /><span style="font-weight:bold"><sup>1</sup></span> &quot;Simple RSS with Perl&quot; by brian d foy, The Perl Review v0 i5, November 2002, <a target="_blank" href="http://www.theperlreview.com">http://www.ThePerlReview.com</a><br /><br /><span style="font-weight:bold"><sup>2</sup></span> <a target="_blank" href="http://search.cpan.org">http://search.cpan.org</a><br /><br /><a target="_blank" href="http://www.theperlreview.com/Articles/v0i7/config.pdf">оригинал статьи на Perl Review (PDF)</a>
</description>
<author>Лобанов Игорь <authors@template-toolkit.ru></author>
<comments>http://forum.template-toolkit.ru/view_topic/topic_id-53.html</comments>
<category>Другие темы, связанные с шаблонами и Perl</category>
<source url="http://forum.template-toolkit.ru/rss/forum_id-8.rss">http://forum.template-toolkit.ru/view_topic/topic_id-53.html?rss</source>
</item>
</channel>
</rss>