Template-ToolkitのWRAPPERでレイアウト制御
my $tt = Template->new( LOAD_TEMPLATES => [ Template::Provider::Encoding->new(INCLUDE_PATH => 'templates') ], STASH => Template::Stash::ForceUTF8->new, PROCESS => $c->{layout}, ); $tt->process($c->{template}, $c->{stash}) || die $tt->error()."\n";
みたいにTTのコンストラクタにPROCESSでレイアウトテンプレート投げて、テンプレート側で
[% META title = 'ページのタイトル' %]
みたいにして、レイアウトから
<title>[% template.title %]</title>
で呼び出せばOK。そんな風に思っていた時期が俺にもありました…
これで進めてたら、METAで渡す値には変数を入れることが出来ないことが判明。マニュアルにも思いっきり
it's not possible to interpolate other variables values into META variables
と書かれていて終了ですよ。回避策も探してはみたけど、やっぱりどうにもなりません。
以前、ウノウラボで「SmartyでRailsライクなレイアウトテンプレートを使う」を書いた時に、「TTだとWRAPPER使って出来る」みたいなことを見かけたので、それを手掛かりに探ってみると、いい感じのアプローチを発見。
WRAPPERだけのためにテンプレートを用意するのはイヤだったので、変態呼ばわりされている4番の方法を採用。この業界、変態は褒め言葉ですから。結局、Perl側のコードはこんな感じ。
my $tt = Template->new( LOAD_TEMPLATES => [ Template::Provider::Encoding->new(INCLUDE_PATH => 'templates') ], STASH => Template::Stash::ForceUTF8->new, WRAPPER => [ \ '[% IF LAYOUT == "none"; content; ELSIF LAYOUT; content WRAPPER $LAYOUT; ELSE; content WRAPPER layout.tt2; END%]' ] ); $tt->process($c->{template}, $c->{stash}) || die $tt->error()."\n";
layout.tt2をこんな感じで用意して、
<html> <head> <title>[% TITLE %]</title> </head> <body> <div id="header"></div> <div id="content">[% content %]</div> <div id="footer"></div> </body> </html>
コンテンツのテンプレートで、
[% TITLE = "$keywordの検索結果" -%] <p>[% keyword %]で検索しました</p>
みたいにしてやればOK。
レイアウトの制御は、
[% LAYOUT = 'layout_login.tt2' -%]
みたいに任意のテンプレートを指定したり、
[% LAYOUT = 'none' -%]
すればレイアウトを適用しない、てな具合にしてみました。今のところ、これで快適。