mirror of
https://github.com/kennethreitz/dive-into-python3.git
synced 2026-06-05 23:10:17 +00:00
229 lines
17 KiB
XML
229 lines
17 KiB
XML
<?xml version="1.0" encoding="MacCyrillic"?>
|
||
<!--
|
||
Source: http://forum.template-toolkit.ru/rss/forum_8.rss
|
||
Expect: MacCyrillic
|
||
-->
|
||
<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>
|