再帰的なHTMLの生成をサポートするRails Plugin:Map as html tags

ってのを作りました。今作っているアプリに必要になったので。

svnでインストールできます。

./script/plugin install http://subversion.assembla.com/svn/map_as_html_tags/trunk

ディレクトリ階層をul/liタグを使って表示したい場合など、再帰的にHTML構造を作成したい時に使います。

使い方

ディレクトリ階層を表すモデルをhtmlに変換する場合以下のようになります。

class Directory < ActiveRecord::Base
  acts_as_tree
end

<id:1, label:root>
  |-<id:2, label:child1>
  |-<id:3, label:child2>

こんな感じのモデルを、以下のように表示します。

<li id="1">
  <a>root</a>
  <ul>
    <li id="2"><a>child1</a></li>
    <li id="3"><a>child2</a></li>
  </ul>
</li>

以下のようなHelperを作成して、モデルを渡します。

module DirectoriesHelper
  include MapAsHTMLTags

  def tree(directories)
    map_as_html_tags(directories) do |directory, context|
      li = HTMLTag.new("li").attr("id", directory.id)
      li << HTMLTag.new("a").text(directory.label)
      li << (HTMLTag.new("ul") << context.proceed(directory.children))
    end.to_html
  end
end

tree(Directory.find(parent_id => nil))
# => 上記のHTMLが返される。

API的なもの

map_as_html_tags
  • ブロックを再帰的に呼び出し、MapAsHTMLTags::HTMLTagsを返します。
  • ブロックの第一引数にはモデル、第二引数にはMapAsHTMLTags::RecursionContextが設定されます。
  • ブロックの役割は、モデルをMapAsHTMLTags::HTMLTagに変換することです。
MapAsHTMLTags::HTMLTag
  • コンストラクタにタグ文字列をとります。
  • attrで属性を設定します。
  • textでinnerTextを設定します。
  • << で子要素か子要素の配列を追加します。
MapAsHTMLTags::HTMLTags
  • to_htmlを呼び出すとHTML文字列を返します。
MapAsHTMLTags::RecursionContext
  • proceedで再帰呼び出しを実行します。
  • depthで0から始まる現在の呼び出し深度を返します。

タスク

とりあえず動くレベルでテストをちゃんと書けてないです。
あと、タグの属性・テキストをエスケープをしてないです。



絶対誰かやってそうなんだけど、探しても見つからなかったのでかっとなって作ってしまいました。後悔はしていない!

このぐらいだとプラグイン化するのも微妙なラインではあるかも…。もし、同じようなことやってる方いらっしゃいましたらぜひ他のやり方教えてください!