How to add virtual method on Template Toolkit

| コメント(2) | トラックバック(0)

Template Toolkitでvirtual methodを追加したいと思ったんですが、ドキュメントを読んでもどうも簡単なやり方が見付からない。仕方がないので最初に下記のようにやりました。

$Template::Stash::LIST_OPS->{ foo } = \&foo;

こうしなけりゃならないのかな?他になにか方法あるのでしょうか…。
追記:はてブでハテナオヤさんが質問してましたが、このエントリで伝えたいことは、vmethodを追加する方法としては、上記の方法やdefine_methodを使うのが正当な方法なのかどうかということと、他の人はどう追加しているのかなという部分になります。

下記のようにインスタンス生成時に追加とかできればいいのに…。

Template->new(STASH => {
    LIST_OPS => { 
        foo => \&foo
    }
);

と思ったら、Template::Stash::define_vmethodという関数がありました(podに書いてない?)。これをTemplate::Context::define_vmethod経由で呼ぶことができるようです。例えばスカラの値に対して1文字ずつスペースを空けるvirtual method(仮にadd_spaceとする)を定義したかったら、テンプレート(vmethod_test.tt)を

[% str.add_space %]

としておいて、

my $tt = Template->new();
my $vars = { str => 'chowww,omawww' };
$tt->context->define_vmethod('scalar', 'add_space', sub { join(' ', split('', $_[0])) });
$tt->process('vmethod_test.tt', $vars);

という感じにdefine_vmethodを使ってdefine_vmethod('virtual methodの種類', '名前', このvmethodのコードリファレンス)と定義してやればよい。出力結果は、

c h o w w w , o m a w w w

となります。ちなみにvirtual methodの種類は「scalar」と「item」がSCALARとして、「hash」がHASHとして、「list」と「array」がARRAYとして定義するために用意されているようです。と、ここまで書いたのですがdefine_methodはpodに書いてないから使うべきじゃないのかな…いやでも先頭に「_」は付いてないしプライベートメソッド的でもないんじゃないの?…とかちょと悶々としてみた。。。どうなんだろ?

Sledgeでこれを使いたいなぁと思ったんですが、Sledge::Template::TT::outputまではTTのオブジェクトは作らない仕様となっているため、やるとしたらこれをオーバーライドしたクラスを作るか、一番最初に挙げた例($Template::Stash::LIST_OPS->{ foo }にコードリファレンスを代入)を使う必要があります。

トラックバック(0)

トラックバックURL: http://blog.clouder.jp/mt/mt-tb.cgi/555

コメント(2)

Sledge::Template::TT はオブジェクトキャッシュしないん(だったとおもう)でアレだとおもわれ。メソッドだとかフィルタ追加とかやるとインスタンス生成時にエライ重くなるるべさ
なんで、TTのキャッシュもつかうけどインスタンスもグローバルにつっこんでまつ

うん、Sledge::Template::TTはキャッシュしてないね。
そうかオブジェクトをキャッシュしてるのか。確かにそっちの方が全体的にパフォーマンスあがりそうだな。。。

コメントする

検索

広告

月別 アーカイブ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.12