Text::Hamlでできること、できないこと
RubyのHamlのつもりでPerlのText::Hamlを使うとつまづいてしまうメモ。
http://search.cpan.org/~vti/Text-Haml-0.990104/lib/Text/Haml.pm
インデントは半角スペースのみ
インデントにタブは使用できず、常に半角スペースでインデントしないとだめ。
いきなりこれでつまづいてたから困った。
日本語を含むときはencodingをundefで指定しないといけない
Text::HamlのデフォルトであるUTF-8の文字コードのファイルでも。
my $haml = Text::Haml->new(encoding => undef);
こうしなければいけないみたい。
内部的にはこうなっていた。
binmode $file, ':utf8'; ... $tmpl = decode($self->encoding, $tmpl) if $self->encoding;
$self->encodingにはデフォルトで'utf-8'が入っているので、2回も文字列フラグをつけようとして(Encodeの)エラーになる。
ただこのままだと文字列フラグがついたまま返ってくるので、返ってきた段階でencode_utf8しないといけない。(もちろんUTF-8の場合)
use utf8; my $haml = Text::Haml->new(encoding => undef); my $output = $haml->render_file('./tmpl.haml', bar => 'ばず'); print encode_utf8($output);
変数は$をつける
%div= "うー!".$nya
my $output = $haml->render_file('var.haml', nya => 'にゃー!', );
<div>うー!にゃー!</div>
$をつけたくないときは、vars_as_subsオプションを有効にする。
%div= "うー!".nya
my $haml = Text::Haml->new(encoding => undef, vars_as_subs => 1); my $output = $haml->render_file('var.haml', nya => 'にゃー!', );
<div>うー!にゃー!</div>
Symbolが見た目使える
%div{ :class => "header" } タイトル
<div class='header'>タイトル</div>
Ruby風文字列挿入#{}が見た目使える
使えるのだけれど、本家のHamlと違い「=」をつけてはいけないので注意!
あとクオートで周りを括ってもだめだよ!
/ 「%div=」ではない %div いつもニコニコ這い寄る混沌、#{$name}です!
my $output = $haml->render_file('interpolate.haml', name => 'ニャルラトホテプ', );
<div>いつもニコニコ這い寄る混沌、ニャルラトホテプです!</div>
()と{}は同時に使用できない
%div(id="header") %div{:id=>"title"} PAGE TITLE
<div id='header'> <div id='title'> PAGE TITLE </div> </div>
%要素に()か{}の片方だけなら問題ないが、両方同時はできない。
%div(id="header"){:class=>"title"} %div(class="header"){:id=>"title"} PAGE TITLE
$haml->error; #=> Tag attributes parsing error
ヘルパ関数登録
ヘルパというよりサブルーチンをHaml内で使うとき。
%div %p = commify($money)."円"
my $haml = Text::Haml->new( helpers => { commify => sub { my $num = $_[1]; # First argument passed to the helper (Text::Haml instance by default). 1 while $num =~ s/(.*\d)(\d\d\d)/$1,$2/; return $num; }, }, ); # or $haml->add_helper( commify => sub { my $num = $_[1]; # First argument passed to the helper (Text::Haml instance by default). 1 while $num =~ s/(.*\d)(\d\d\d)/$1,$2/; return $num; }, );
<div> <p> 1,000,000円 </p> </div>
if else end
本家のHamlはendが不要だが、Text::Hamlはifの評価にかっこも要るし、ブレースも要る。
%div - if (1) { OK - } else { NG - }
<div> OK </div>
空白の行が出力されてしまうが、直後に何かある場合はなぜかつまる。
%div - if (1) { OK - } else { NG - } %p paragraph
<div> OK <p>paragraph</p> </div>
タグ内の改行は調整できない
%div %div< %div OK
<div> <div> <div>OK</div> </div> </div>
<div><div><div>OK</div></div></div>
とはならない。
Text::Hamlの実装が面白いのであとでよむ。