2004年08月22日 (日)
Template-Toolkitで配列→x重ループ
Class::DBIかなんかを使って、データの配列を取り出してそのまま、Template-Toolkitにデータを渡すっていうやり方をしてると。
デザインの都合で、折り返しが有るようなデザイン(例えば Livedoor Blogの真ん中辺にある「話題のblog」)に対応するとき、テンプレートは
[% i = 0 %] <table> <tr> [% FOR blog = wadai %] <td>[% blog.image %][% blog.title %]</td> [% IF i % 3 = 0 %]</tr><tr>[% END %] [% END %] </tr> </table>
こんな書き方になってしまいます。(もっと上手い書き方があったかも。)
例によって、この書き方だと、表示のための処理ではあるけどプログラムっぽいし、テンプレートとしても、いまいち美しくありません。
かといって
<table> [% FOR blog = wadai %] <tr> [% FOR v = blog.loop %] <td>[% v.image %][% v.title %]</td> [% END %] </tr> [% END %] </table>
の様なテンプレートにするためには、プログラム側で配列を2重ループに対応した配列に作り直す必要があります。デザイン的な都合のために、プログラム側で対応するのはヤッパリいまいち。。。
と言うことで、とりあえずの折衷案。
TTに渡すパラメータにこんなの作って、セットされようにしておきます。(MVCでいうところのモデル部分には書かないでと言う意味です。ボクはSledge使っているのでPlugin作りました。)
nest_loop => sub {
my $array = shift;
my $count = shift;
my $name = shift || 'next' ;
my @loop;
while (scalar(@$array)) {
push(@loop, {$name => [splice @$array, 0, $count]});
}
return \@loop;
}
これは、配列のリファレンスと、数値をもらって、
[1,2,3,4,5,6,7]
という配列を
[
{next => [1,2]}.
{next => [3,4]}.
{next => [5,6]}.
{next => [7]}.
]
な形に変換してくれる、無名関数です。
で、テンプレートでは
<table> [% FOR blog = nest_loop(wadai, 2) %] <tr> [% FOR v = blog.next %] <td>[% v.image %][% v.title %]</td> [% END %] </tr> [% END %] </table>
の様に使えます。もちろん、wadaiは Class::DBI から取ってきたスの配列でOKです。なか、探せばPluginとか有りそうな気もしたんですが、どういうキーワードで探せばイイか英語わかんらんから探せねーよ!!(逆ギレ)ということで、自作シマシタとさ。
posted by takefumi
|
この日記へリンク
|
コメント(2)
|
トラックバック(0)
この日記へのトラックバック
この日記へのコメント
Template::Plugin::Tableというのがありますがどうでしょう。
#!/usr/bin/perl
use strict;
use Template;
Template->new->process(?*DATA, {array=>[1..10]});
__END__
[%USE table(array,rows=5)%]
<table>
[% FOREACH row = table.cols %]
<tr>
[% FOREACH item = row %]
<td>[% item %]</td>
[% END %]
</tr>
[% END %]
こんな感じです。

