「ザリガニが見ていた...。」さんのAmrita2紹介記事

「ザリガニが見ていた...。」さんでAmrita2についての解説記事を書いていただきました。

「ザリガニが見ていた...。」さんのRailsについてのエントリは参考になるものが多くて、私もレビュアブルマインドを開発する時や、現在行なっているRails2.0対応の作業で参考にさせていただいています。

そういうブログでAmrita2について書いていただけたことは、本当にありがたいことです。特に、Rails(ERB)に慣れている方からの視点でAmrita2について書いてもらうと、開発している側にはわからないことがいろいろ見えてきます。

そこで、この3つの記事に対して、補足、感想等を書かせていただきます。

インストールについて

id:zariganitoshさんは、tarボールを vendor/plugin に展開して使用されているようですが、UsingWithRailsに書いてあるように、gemでインストールすることもできます。

$ sudo gem install amrita2
$ cd (アプリケーションルート)
$ mkdir vendor/plugins/amrita2
$ cp /usr/lib/ruby/gems/1.8/gems/amrita2-2.0.1/init.rb vendor/plugins/amrita2/

/usr/lib/ruby/gems/1.8/gemsは、環境によって違いますが、gemsがインストールされているディレクトリです。

ERbからの段階的な移行

最初からAmrita2のすべてを理解する必要はなく、便利だと思う機能から利用していけば良いのだ。

これは、まさに私が意図していたことで、従来のERbテンプレートから少しづつ段階的に移行していけるように工夫しています。

次の例のように(これはanalyticsのjsコードを挿入している所)、<<%< というマークから段を下げた部分は、ERbテンプレートと同じように扱われます。

    <<%<
      <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
      </script>
      <script type="text/javascript">
        var pageTracker = _gat._getTracker("<%= $rmind_config[:google_analytics_account] %>");
        pageTracker._initData();
        pageTracker._trackPageview();
      </script>

CDATAで囲んだ所も同様にERbとして扱われます。

だから、Amrita2の仕様やエラーメッセージがよくわからない場合は、すぐに、ERbに戻ってそこだけERbで書くことができます。

出力ソースのインデント

ブラウザの描画結果はまったく同じなのだが、やはりHTMLソースも改行されて欲しい...。

Amtita2の出力結果は、はっきり言ってインデントがおかしくて、人間が見るには見づらいものになっています。

後の記事にありますが、これを補うには、tidy等の外部コマンドをフィルターとして組みこんでインデントしてください。

次のようにすると、デバッグ時のみインデントされた出力を行なうことができます。プロダクション環境では、余分なコマンド呼び出しを行ないません。

(config/environment.rb)
if ENV['RAILS_ENV'] == "development"
  IndentByTidyIfDebug = Amrita2::Filters::CommandFilter['tidy -q -xml -indent -utf8']
else
  IndentByTidyIfDebug = nil
end
(layout/application.html.a2)
<<html :| IndentByTidyIfDebug <
  <<head<
    <title>Reviewable Mind</title>

ただし、tidyのインデントは、railsjavascript_tag の出力を壊してしまうようで、javascriptが正しく実行されないことがあります。(他に適当なHTMLのプリティプリンタが無いか物色中です)

表記述の仕様

ここは(ここも)、説明が完全に不足していた所ですが、仕様を読み取ってわかりやすくまとめていただけました。

  • 「|」で区切った範囲が、tdタグの1セルと解釈される。
  • 「||」で区切った左側で属性を指定すると...
    • その行はtdタグの属性値の指定になる。
    • 属性値の指定が無ければ、半角スペースで埋めておけば良い。
  • 上下のハイフンの連続は、無くてもOK。
  • 「|」の間隔も最低1スペースあればOK。(インデントを揃えておかないと、この書式の意味は無いが。)
  • ちなみに、「||」の右側の「|」を「||」に置き換えるとthタグと解釈された。
  • td、th以外の目的で「|」を利用するときは、エスケープ「\|」しておく必要がある。

まったくその通りです。

この記法は激しく好みが分かれる所のような気がしますが、次のようにフォームと組み合わせた場合等は、有効ではないかと思います。

次の例は、レビュアブルマインドのサインアップフォームです。

  <%
      signup_form = amrita_define_form(:user, :action=>:login) do |f|
        f.text_field :login
        f.password_field :password
        f.add_field_element :password_confirm, password_field_tag(:password_confirm, "")
        f.text_field :email, :size=>50
        f.add_field_element :terms_of_use, check_box_tag(:terms_of_use, false)
        f.add_field_element :link_to_terms_of_use, link_to('terms of use', '/term.html')
      end
   %>

  << :signup_form | AcceptData[:hook] <
    <<two_columns_form<
      <<<---------------------------------------------------------------
        ||| Login ID:            | <<:login>>                          |
      <<<---------------------------------------------------------------
        ||| Password:            | <<:password>>                       |
      <<<---------------------------------------------------------------
        ||| Password(confirm):   | <<:password_confirm>>               |
      <<<---------------------------------------------------------------
        ||| E-Mail:              | <<:email>>                          |
      <<<---------------------------------------------------------------
        ||| Terms of use:        | <<:terms_of_use>> &#160;            |
        |||                      | I have read and agree to the &#160; |
        |||                      | <<:link_to_terms_of_use>>           |
      <<button_bar  <---------------------------------------------------
        <<:| Join[:nbsp]<
          %= submit_tag _('Signup')
          %= link_to _('Login'), :action => 'login'

two_columns_formは、マクロという機能を使用して、tableタグに置き代わりますが、ここに直接 table タグを指定してもかまいません。

ちなみに、この例では、lableタグを後から埋めこむためにマクロを使用しています。

Rubyブロック内のルール

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

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


行頭の%の記述ですが、ここは、ちょっと特殊な処理を行なっています。

  • 行頭に%が続く限り、(インデントを無視して)一つのCDATAブロックとしてまとめる(後にERbとして一括処理)
  • 行頭が%=だったら、その1行分の結果を出力する処理に変換

この記法は単発の短い処理を書くのには適していますが、ブロックを使う処理や、複数行にまたがる処理をERbで書く時は、次の書き方の方がおすすめです。

<<%<
  <% 3.times do %>
    <p>
      index.html.a2
    </p>
  <% end %>