Amrita2での書き方例OKとNG

以下は自分自身の理解不足からやってしまった、AmXML記法での書き方例。忘れたくないのでメモ。

  • NGは失敗例(エラーが発生)
  • OKは成功例(予想通りの表示結果)

1行で書きたい

# 時には、以下のように書きたくなるが、それはダメ...。
# NG
  <<table<
    <<tr<
      <<th %= _("Slip|Number")>>

# ちゃんとインデントを増やす必要がある?
# OK
  <<table<
    <<tr<
      <<th<
        %= _("Slip|Number")

# またはHTMLタグで書く。
# OK
  <<table<
    <<tr<
      <th><%= _("Slip|Number") %></th>

ハッシュを定義して利用

# {}の範囲はRuby式のハッシュとして評価してくれる。
# OK
  <<table<
    <<tr<
      <<{:title => _("Slip|Number")}<
        <<th :title >>

# 複数行になる場合は、{の右側にコードを書いてはダメ?
# NG
  <<table<
    <<tr<
      <<{:title => _("Slip|Number")
        }<
        <<th :title >>

# OK
  <<table<
    <<tr<
      <<{
         :title => _("Slip|Number")}<
        <<th :title >>

# OK
  <<table<
    <<tr<
      <<{
         :title => _("Slip|Number")
        }<
        <<th :title >>



# ハッシュはタグに含めることも出来る。
# OK
  <<table<
    <<tr{:number => _("Slip|Number")}<
      <<th :number >>

Rubyブロック内のルール

# ブロック内にRuby式以外が存在するとエラー。
# NG
% 3.times do
  <p>
    index.html.a2
  </p>
% end

# ブロック内がすべてRuby式なら大丈夫。
# OK
% 3.times do
  %= "<p>"
    %= "index.html.a2"
  %= "</p>"
% end

form_forブロック内のルール

# ブロック引数を利用しているとエラー。
# NG
% form_for :slip, :url=>{:action=>:index} do |f|
  %= f.text_field :number
% end

# ブロック引数を利用しなければ大丈夫。
# OK
% form_for :slip, :url=>{:action=>:index} do |f|
  %= text_field :slip, :number
% end
  • しかし、ブロック引数を利用しないform_forは考えられない。対策は以下。
    • amrita_define_formで書き換える。
    • またはform_forを利用しているファイルは、ERbで記述する。

ERbブロック(<<%<)のルール

  • AmXML記法では、「<<%<」のように書くと、以下のインデントをERbブロックと見なしてくれることが判明!
  • つまり、Rubyブロック、form_forブロックで悩んでいたことは、以下のようにすれば素晴らしくシンプルに解決できるのでした。
# OK
<<%<
  <% 3.times do %>
    <p>
      index.html.a2
    </p>
  <% end %>

# OK
<<%<
  <% form_for :slip, :url=>{:action=>:index} do |f| %>
    %= f.text_field :number
  <% end %>
  • このことは、すべての.erbファイルは、素晴らしく簡単に.a2ファイル(Amrita2のAmXMLファイル)に移行できることも意味する。
    • 1行目に「<<%<」を追記して、それ以下を1レベルインデントするだけでOK。
    • ただし、ERbブロックでは基本的にAmXML記法が利用できなくなる、と考えていた方が良さそう。(当然のことだが...。)
# OK
<<%<
 <% 3.times do %>
  <<h1<
    Listing slips
    <%= "Listing slips" %>
 <% end %

# <<:title>>のような記法も利用できない。
# <% %>を%とは書けない。
# NG
<<%<
 % 3.times do
  <<h1<
    <<:title>>
    %= "Listing slips"
 % end
    • <![CDATA[  ]]>でも同等の結果に。
# OK
<![CDATA[
<% 3.times do %>
  <<h1<
    Listing slips
    <%= "Listing slips" %>
<% end %
]]>

サニタイズの制御

# 単なる文字列として表示される。(<a href="/slips">Index</a>と表示されクリック不可能)
# NG
<<{:index_link => link_to("Index", :action=>:index)}<
  <<:index_link>>

# Indexリンクとして表示される。(Indexと表示されクリックするとIndexページへ移動)
# OK
<<{:index_link => link_to("Index", :action=>:index)}<
  <<:index_link | NoSanitize>>

変数$_

# 変数$_がARモデルの配列の場合、破壊的に代入すると、おかしな値になる。
# NG 結果→"1"
% @tests = [Slip.new(:total_yen=>"1000")]
<<table<
  <<tr :tests <
    % $_[:total_yen] = number_with_delimiter($_[:total_yen])
    <<td align="right" :total_yen <

# ハッシュの配列なら問題ない。
# OK 結果→"1,000"
% @tests = [:total_yen=>"1000"]
<<table<
  <<tr :tests <
    % $_[:total_yen] = number_with_delimiter($_[:total_yen])
    <<td align="right" :total_yen <

# ARモデルであっても、破壊的代入でなければ問題ない。
# OK 結果→"1,000"
% @tests = [Slip.new(:total_yen=>"1000")]
<<table<
  <<tr :tests <
    % $_[:total_yen_delimiter] = number_with_delimiter($_[:total_yen])
    <<td align="right" :total_yen_delimiter <