HTML::Template::Plugin::Dotを使ってみた
HTML::TemplateにTTのようなdotでメソッドを呼び出す機能を持たせるHTML::Template::Plugin::Dotを使ってみた。0.06でloop内の動作もよくなってきた感じがするので試してみることにした。
UnixUserの伊藤直也さんの連載の「作って学ぶ、いまどきのWebサービス」を参考に、OpenSearchを利用したアプリケーションを作ってみることにする。
コマンドライン版をまず制作。
my $engine = WWW::OpenSearch->new($osxml);
my $feed = $engine->search($word);
my $tmpl=HTML::Template::Pluggable->new(
scalarref=>?$template,
die_on_bad_params=>0,
loop_context_vars=>1,
case_sensitive=>1
);
$tmpl->param('result',$feed);
テンプレートは、
<ul> <!-- TMPL_LOOP NAME=result.items:item --> <li><!-- TMPL_VAR NAME=item.title ESCAPE=HTML --></li> <!-- /TMPL_LOOP --> </ul>
こんな感じ。case_sensitiveをOnにしておくのが吉です。大文字小文字が混じったメッソドを呼び出すには必要です。
ただしこのサンプル。HTML::Templateにpatchを当てないとうまく動かない。LOOPは動くけど中身が入らない。これはHTML::Templateがsubクラスを作りにくい構造になっているためです。しかし、本当にpatchを当てるのは少々面倒なので、HTML::Templateの_parseメソッド650行をコピペして、Perlスクリプト中に埋め込みます。んで上述のpatchを参考に
= HTML::Template->_new_from_loop(
のあたりを書き換えます。下のようになります。
sub HTML::Template::_parse{
my $self = shift;
my $options = $self->{options};
〜〜中略〜〜
# does _parse() - sub-templates get their parse_stack and
# param_map fed to them already filled in.
my $pkg = ref $self;
$loop->[HTML::Template::LOOP::TEMPLATE_HASH]{$starts_at}
= $pkg->_new_from_loop(
parse_stack => $parse_stack,
〜〜中略〜〜
# get rid of filters - they cause runtime errors if Storable tries
# to store them. This can happen under global_vars.
delete $options->{filter};
}
これで動かすことができました。スクリプトはこちらに置きました。
次に、Web版。前述のUnixUserの記事と同じようにCGI::Applicationを使ってみました。。HTML::Template::Plugin::Dotを利用するためのCGI::ApplicationのプラグインCGI::Application::Plugin::HTPluginDotを書いて、HTML::Template::_parseはその中に埋め込んだ。
デモはこちら。
ページがそんなにないのでdispatchを利用しなかったのと、ページ移動のFOREACH部分は実装していません。この部分は別方法を考えるしかないなぁ。
ソースはこちら。
ちょっと使えそうな気がした。