Template-Toolkitでマルチバイトな話
先に言っておくと、hide-kさんのまとめが分かりやすいです。
最もCatalystを使う際にと言う事ですが。
utf8フラグを立てないでTTを使う場合
ソース自身はutf8で書くんですけど、
#!/usr/bin/perl use strict; use warnings; use Carp::Clan; use Path::Class; use Template; my $base_dir = dir($ENV{HOME}, qw/tmp tt_test/); my $template = Template->new({ COMPILE_DIR => $base_dir->subdir('tt.cache')->stringify, COMPILE_EXT => 'c', }); my $output = ''; my $vars = { id => 'ZIGOROu', name => 'ますだ じごろう' }; $template->process(\*DATA, $vars, \$output) || carp $template->error; print $output; __DATA__ [% id %] [% name %] [% name | truncate(7) %]
こうすると指定したディレクトリにtt.cacheってディレクトリが出来て、コンパイル済みのファイルが出来ます。
が、やってみると分かりますが、truncateの出力で悲しい目に遭います。*1
utf8フラグを立てる場合
こんな感じ。
#!/usr/bin/perl use strict; use warnings; use Carp::Clan; use Path::Class; use Template; use Template::Provider::Encoding; use Template::Stash::ForceUTF8; my $base_dir = dir($ENV{HOME}, qw/tmp tt_test/); my $template = Template->new({ LOAD_TEMPLATES => [ Template::Provider::Encoding->new({ COMPILE_DIR => $base_dir->subdir('tt.cache')->stringify, COMPILE_EXT => 'c', }) ], STASH => Template::Stash::ForceUTF8->new, }); my $output = ''; my $vars = { id => 'ZIGOROu', name => "ますだ じごろう" }; $template->process(\*DATA, $vars, \$output) || carp $template->error(); utf8::encode($output); print $output; __DATA__ [% id %] [% name %] [% name | truncate(7) %]
ほとんど変わらないんですが、
を使ってるって事が大きく違います。
前者は渡した変数をテンプレート内部でutf8フラグを強制的に立ててくれる物で、後者はテンプレートそのものを指定したencodingでutf8フラグを立ててしまうという物です。
あとはこのようにTemplate::Providerの子孫クラスをnewしてLOAD_TEMPLATESに渡すので、事前にProviderに必要なconfigをProvider自体に渡しておかないとトラブルがおきます。
例としては、
- 通したはずのINCLUDE_PATHからテンプレートファイルが見つからない
- COMPILEされるはずがされない
などなど。
詳しいオプションは、
を見て下さい。
まとめ
TTの枠組みくらい理解しておかないとダメだなと思った><
実践あるのみですね。
*1:ここはutf8フラグが立ってないので当然っちゃ当然ですが