end0tknr's kipple - web写経開発

太宰府天満宮の狛犬って、妙にカワイイ

Template::ToolkitのURL FILTERの不審な挙動と回避法

Template::ToolkitのFILTER機能は利用されている方も多いと思います。
現在、Template::Filters ver.2.86 を使用していますが(と言うより、何でも渡せます)、urlエンコード(uri, urlフィルタ)の挙動がおかしい気がします。

次のようなscriptを実行すると、urlフィルタとunpack()の結果が一致しませんでした。

perl script

#!/usr/local/bin/perl
use strict;
use warnings;
use Template;

my $template = Template->new();
my $val = "京";

$template->process("foo.tt", {val=>$val});
$val =~ s/(\W)/'%' . unpack('H2', $1)/ego;
print "UNPACK:     $val\n";

template

URL FILTER: [% val | url %]

実行結果(urlフィルタとunpack()の結果が一致しない...)

URL FILTER: %C3%A4%C2%BA%C2%AC
UNPACK:     %e4%ba%ac

このことは、次のurlにも記載されており、更にTemplate::Filtersに対するpatchも紹介されています。

http://cyberlib.enterbrainz.com/1189006458.html

methodを渡して、urlエンコードの不審な挙動を回避

Template::Toolkitのテンプレートには、methodを渡すこともできますが、私の場合、このことを利用して、urlエンコードの不審な挙動を回避してみました。

#!/usr/local/bin/perl
use strict;
use warnings;
use Template;

my $template = Template->new();
my $val = "京";

$template->process("foo.tt", {val=>$val,url_encode=>\&url_encode});
$val =~ s/(\W)/'%' . unpack('H2', $1)/ego;
print "UNPACK:     $val\n";

sub url_encode { #このmethodをテンプレートに渡します
    my ($val) = @_;
    $val =~ s/(\W)/"%" . unpack('H2',$1)/ego;
    return $val;
}
URL FILTER: [% url_encode(val) %]
URL FILTER: %e4%ba%ac
UNPACK:     %e4%ba%ac

この方法の場合、urlエンコードを行っているテンプレートを全て変更する必要がありますが、変更箇所が少ないのであれば、このmethod渡しの方法でもよいのかなと思います。