のみまくし日記

毎日が文化祭の前日、そんな環境っていいですよね。この日記は未来の自分へのメッセージです。

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とか有りそうな気もしたんですが、どういうキーワードで探せばイイか英語わかんらんから探せねーよ!!(逆ギレ)ということで、自作シマシタとさ。

Perl 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 %]

こんな感じです。

posted by nagayama at 2008年12月03日 13時07分 #

おー。これこれ、ありがとうござます!

TT入れると標準で入ってくるヤツなのね、知らなかったです。

posted by きむら at 2008年12月03日 13時07分 #