目次

タグ追加の参考サイト

後者は、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>

すると。。。。無事、こういう風に展開される。

ext03

あとは、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にもインストールできるでしょう。動作保障はしません。。コードの参考までに、です。