Catalyst::Helper::View::TTSite を使ってみたら、雛形のテンプレートで TT の WRAPPER がみたことがない使われ方をしていたので、調べてみたら TT の Automatic Wrapper という仕組みだった、という話。
今までの自分の TT の使い方。
普段自分が Web アプリなんかで TT を使う時の使い方は、header.tt と footer.tt とか作って、tt_process で指定するテンプレがそいつらを含めてるという、↓のような感じ。
header.tt。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>[% title %]</title> </head> <body>
footer.tt。
<div id="footer">© 2006 ziguzagu</div> </body> </html>
で、コントローラーで指定するテンプレ、index.tt とかをこう。
[% INCLUDE header.tt title="タイトル" %] <p>なかみ</p> [% INSERT footer.tt %]
これはこれで、header.tt / footer.tt の再利用が出来るのはいい。ただ、
- 各テンプレート内でHTMLの開始タグと終了タグの対応がとれてない
- ベースになるテンプレート全部で同じ INCLUDE や PROCESS / INSERT を書く必要がある
とかいったあたりがあんまり美しくないなぁ、とは思ってたり。でもそこで思考停止…。
そこで、AutoWrapper。
TT のインスタンスを作るときに、PRE_PROCESS や POST_PROCESS オプションにテンプレートを指定するのと同じ形で、WRAPPER オプションに一番外側になるテンプレートを指定すると、tt_process で生成される出力が、WRAPPER で指定したテンプレの content になる、というのが TTSite の雛形をみて知った。
たとえば、
wrapper.pl
#!/usr/bin/perl
use strict;
use warnings;
use Template;
my $tt = Template->new({
WRAPPER => 'wrapper.tt',
});
$tt->process('content.tt');
というのを作って、wrapper.tt には HTML の全体像を記述。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>[% template.title %]</title> </head> <body> [% content %] </body> <div class="footer">© 2006 ziguzagu</div> </html>
content.tt には、[% content %] に入れたい部分を記述。
[% META title = 'Wrapper Test' %] <p>Hello Wrapper!!</p>
で、実行した結果は、こうなる。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Wrapper Test</title> </head> <body> <p>Hello Wrapper!!</p> </body> <div class="footer">© 2006 ziguzagu</div> </html>
META が実はいい感じ(METAもほとんど使ったこと無かった…)。
WRAPPER を入れ子にしてみる。
WRAPPER は複数テンプレートを入れ子にも出来る。
wrapper.tt をこんな風に。
<!-- BEGIN auto wrapper --> [% content WRAPPER html.tt + inner.tt %] <!-- END auto wrapper -->
親テンプレの html.tt。
<!-- BEGIN html.tt --> <title> [% template.title %] </title> <content> [% content -%] </content> <!-- END html.tt -->
これの content に、次に指定した inner.tt が入る。
inner.tt。
<!-- BEGIN inner.tt --> [% content %] <!-- END inner.tt -->
inner.tt の content には、tt_process で指定した content.tt が入ってくる。
で、結果はこうなる。
<!-- BEGIN auto wrapper --> <!-- BEGIN html.tt --> <title> Wrapper Test </title> <content> <!-- BEGIN inner.tt --> <p>Hello Wrapper!!</p> <!-- END inner.tt --> </content> <!-- END html.tt --> <!-- END auto wrapper -->
content をどんどん入れ子に。いいね。
ということは
個別のページ専用の分岐とかを META とかの指定でうまい具合にやれば、無駄な毎回同じテンプレ INCLUDE とかなくなるような気がする。。。
ちなみに、↓の本の Chapter.2 に、『Using an Automatic Wrapper Template』という項がしっかりあって、ちゃんと解説されているという事実。ttree 使ったサンプルとかも。TTSite 使うまでは目もくれなかった。。。

- Perl Template Toolkit
- Darren Chamberlain David Cross Andy Wardley
- Oreilly & Associates Inc 2004-03
- 売り上げランキング : 3228
- 評価
by G-Tools , 2006/11/22

Comments