Amrita2の am:for の使い方が良く分かりません
今、Ramazeさんのテンプレートエンジンのきちんとした比較を行なうために、各テンプレート用ベンチマークスクリプトの点検をしています。それで困ってしまうのが私のAmrita2に対する理解の不十分さです。Amrita2は何せ情報が少ないので頑張ってはみるのですがなかなか思った通りになりません。
非常に初歩的な点だろうと思うのですが、今問題になっているのは、am:forの使い方です。
<html> <body> <span>Hello, World!</span> <span>Hello, World!</span> <span>Hello, World!</span> <span>Hello, World!</span> <span>Hello, World!</span> </body> </html>
以上のようなものを出力したくて、次のように書こうと思いました。
# render_with {:hello => "Hello, World!"} << html < << body < << [1..5] < <<span:hello>>
で、これはダメなわけです。たぶん "[1..5]" のところで $_ が変わっちゃうから、<<:hello>> が展開できないのだろうと思います。私は"Hello, World!"のような文字列を繰り返しで出力するために am:for を使おうと考えたのですが、こういう目的で am:for を使うのは的外れなのでしょうか。
もちろん文字列を直接埋め込めばいいのですが、それは諸事情あって避けたく思います。またこうした箇所をERbで書くと非常に簡単なのは分かっているのですが、なるべくAmrita2のやり方で書きたいと思っています。
ところで、Amrita2に関するこういう初歩的な質問って、どこですれば良いのかな?
追記:少しだけ分かってきたかも?
実験してたら、なんかすっごい勘違いしてるのかも、と思うようになってきました。というかこれは勘違い以外の何者でもないのだろうと思います。まず、am:for は次のように使えます。
<< div [1..5] >>
この結果は次のようになります。
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div>
またam:forを利用して次のようにも書けます。
<< div [["Hello, World!"] * 5] >>
この結果は次のようになります。
<div>Hello, World!</div><div>Hello, World!</div><div>Hello, World!</div><div>Hello, World!</div><div>Hello, World!</div>
大部やりたい事に近付いてきた気がします。ただし
<< span [["Hello, World!"] * 5] >>
とすると、もちろんspanが消えてしまうので、結果は
Hello, World!Hello, World!Hello, World!Hello, World!Hello, World!
となってしまいます。だからと言って
<< span [["<span>Hello, World!</span>"] * 5] >>
のようにすると結果は次のようになります。
<span>Hello, World!</span><span>Hello, World!</span><span>Hello, World!</span><span>Hello, World!</span><span>Hello, World!</span>
というわけでサニタイズされちゃうのでダメです。そもそもこのような書き方だと全くテンプレートの意味がないと思いますので、当然こういう書き方をして良い訳がありません。
さらにはもっと無茶をして
<< span [[["<span>Hello, World!</span>"]] * 5] >>
とすると何も出力されないという結果に。ここまで来ると絶対に am:for の目的外使用であることは明らかです。
とりあえずのところ、
<html> <body> <span>Hello, World!</span> <span>Hello, World!</span> <span>Hello, World!</span> <span>Hello, World!</span> <span>Hello, World!</span> </body> </html>
のようなものを出力したい場合には、am:forを使うのではなく、次のようにフィルターを組み合わせて書くことが出来るのが分かりました。
# tmpl.render_with(:hello => "Hello, World!") << html < << body < << div < <<:hello | Format["<span>%s</span>"] | NoSanitize | Repeat[5]>>
この結果は次のようになります。
<html><body><div> <span>Hello, World!</span><span>Hello, World!</span><span>Hello, World!</span><span>Hello, World!</span><span>Hello, World!</span> </div></body></html>
これがベストであるとも思えないのですが、とりあえず pure amrita2 な感じになりました。ていうかフィルターの充実っぷりすごいですね。もっとフィルターの方に注目しなけれならないのかな、と感じました。