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部分は実装していません。この部分は別方法を考えるしかないなぁ。
ソースはこちら。
ちょっと使えそうな気がした。