Xslate上でフォーム処理をしようとしたらいろいろハマったのでCookbook書きました。
http://search.cpan.org/dist/HTML-Shakan=HTML::Shakanなどのフォームビルダーは、アプリケーションコードで出力の際にmark_raw()でraw stringにしてください。
HTML::FillInFormを使う場合がちょっと厄介で、簡単な方法がなかったので*1新しい構文を加えることにしました(0.1038から)。blockに対してその場でフィルタをかますことができるようになります。
Cookbookからのコピペですがこんな感じです。
#!perl -w use strict; use Text::Xslate qw(mark_raw); use HTML::FillInForm; sub fillinform { my($q) = @_; return sub { my($html) = @_; return mark_raw(HTML::FillInForm->fill(\$html, $q)); }; } my $tx = Text::Xslate->new( function => { fillinform => \&fillinform, }, ); my %vars = ( q => { foo => "<filled value>" }, ); print $tx->render_string(<<'T', \%vars); FillInForm: : block form | fillinform($q) | raw -> { <form> <input type="text" name="foo" /> </form> : } T __END__
さらに、いちいちfillinform()を書くのがかったるい!という方向けに、HTML::FillInForm::Liteにはエクスポート可能なfillinform()関数を追加しました(1.09から)。fillinform($html, $data)とすれば$htmlにfill()した結果を返し、fillinform($data)とすれば上記のようなcurry化したサブルーチンを返します。
つまり、Text::Xslate->new( module => ['HTML::FillInForm::Lite' => [qw(fillinform)]] )とするだけでfillinform($q)フィルタが使えるので便利です。ただしrawフィルタが必要なのは変わりません。安全第一。
*1:マクロを定義してそれを明示的に呼び出すしかありませんでした。