目次
- 前回(モデルと管理画面追加)
- 今回(タグの追加)
タグ追加の参考サイト
- http://wiki.github.com/radiant/radiant/adding-custom-radius-tags
- http://github.com/radiant/radiant/blob/master/app/models/standard_tags.rb
後者は、Radiant内で実際に使われているタグ定義、要はソースの一部。これが一番参考になる。チラチラ見ながら読み進めていただきたい。
タグ用のDSLの概要
vendor/extensions/cash_memo/app/models/cash_item_tags.rb というものを作ってみよう。models以下に作成することが多いようだ。
1 2 3 4 5 6 | module CashItemTags include Radiant::Taggable class TagError < StandardError; end ... end |
タグを作成するためには、以下の流れでモジュール内に宣言していく。
- desc メソッド: 説明を書く。%{}とかで囲って書いてる場合が多い。また、Textile記法を用いたりできる。
- tag メソッド: 実際の挙動をブロック内に記述する。メソッドの引数はタグ名。また、ブロック内には「tag」という変数を投げ込める
この「tag」オブジェクトは、正体は「Radius::TagBinding」というクラスのようだ。以下のようなメソッドが使える。
- Radius::TagBinding#expand: そのタグで囲ったテキストを、その場で展開する。
- Radius::TagBinding#attr: そのタグで指定した、「name=”value”」みたいな属性をパースし、ハッシュの形で
1
tag.attr["name"]
のようにアクセスできるようにする。
- Radius::TagBinding#locals: そのタグと、そのタグの子要素となるタグ内で共通に使用できる変数をセット/アクセスする。tag.local自体はOpenStructを継承したオブジェクトのようで、
1 2
tag.locals.hoges = Hoge.all tag.locals.hoges.first
のように使える。
これは、実際のコードをみて行った方がわかりやすいかな。。。
ということで拙作のタグの一部を。。「CashItem」モデルは、前回からの続きということで。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # 何もしない、ネームスペースの定義だけのタグは、とりあえず「tag.expand」としておこう tag 'cash_items' do |tag| tag.expand end tag 'cash_items:each' do |tag| begin # localsにモデルをセット # ここでセットすると、 cash_items:each:* のネームスペースの子要素内で参照できる、ということ tag.locals.items = CashItem.all ret = [] iterated_items = tag.locals.items # モデルの個数だけ、 r:cash_items:each タグでくくった要素を繰り返し出力する iterated_items.each do |item| tag.locals.item = item ret << tag.expand end ret rescue => e "タグに誤りがあるようです:#{e.class}, #{e.message}" end end # 名前だけ tag 'cash_items:each:item' do |tag| tag.expand end # cash_items:each 内で、各モデルの各属性に参照する tag 'cash_items:each:item:name' do |tag| tag.locals.item.name end # tag.attr はこんな感じで使える tag 'cash_items:each:item:paid_at' do |tag| tag.locals.item.paid_at.strftime((tag.attr["format"] || "%Y/%m/%d(%a) %H:%M:%S").strip) end # 以下、各属性へのアクセッサーを宣言…… |
タグの有効化は、 vendor/extensions/cash_memo/cash_memo_extension.rb に以下の要領で追記。
1 2 3 | Page.class_eval { include CashItemTags } |
で、ある程度小遣い帳の項目を登録したら、CMS管理画面側で、こんな感じで記事を登録(Textile filter)。
1 2 3 4 5 6 7 8 | <r:cash_items:each> h3. <r:item:name /> * 使用金額:<r:item:amount /> * 購入者:<r:item:user_name /> * 購入日時:<r:item:paid_at format="%Y年%m月%d日 (%H:%M)" /> bq. <r:item:note /> </r:cash_items:each> |
すると。。。。無事、こういう風に展開される。
あとは、cash_item:each タグに属性を設定し、順番なり抽出条件なりを変えたりとか、いろいろできる。とにかく standard_tag の書き方が一番参考になるので、作るつもりの人はみておいた方がいいだろう。
まとめ
- Radiant Extensionとは言いながら、実際の作り方、コードの感じはほぼまったく素のRailsに近い。
- Tagの記述DSLは多少コツがいるが、十分に柔軟。
- Radiantは、CMSというか、Railsの上にさらに覆い被さるウェブサイトフレームワークといった感じがする。Extension次第でかなり柔軟なサイト構築が出来そう。
ということで、日本語化も無事されつつあるということで、もっと色々Extensionが増えるといいですね~。
今回作ったExtension、今後の課題は:
- Spec全然書いてない。
- 例外処理が非常に甘いと思う。
ソースコード is here
1 | git clone git://github.com/udzura/radiant-cash_memo-extension.git vendor/extensions/cash_memo |
で、他のRadiantにもインストールできるでしょう。動作保障はしません。。コードの参考までに、です。





