[Bilbo]BilboのMVC
http://mt.endeworks.jp/d-6/2008/03/db-1.html
BilboはDBを使わないけどMVCで実装している。
良い機会なのでBilboの超シンプルなMVCの実装を紹介。 このMVCを実現してるコア(bilbo.rb)は81行。
モデル
日記の記事はモデルとして管理される。具体的にはEntryクラスが記事を扱うモデルである。
entries = Entry.find('200803', :limit => 5)
こんな風にすると2008年3月の記事オブジェクトを5個取り出すことができる。
このEntryクラスの実装は30行。 この30行には、記事をHTMLに変換するコンパイラの登録と変換処理も含まれている。 このEntryクラスはBilboにとって最大の機構。30行なんて長すぎるのでコードは省略。
記事オブジェクトは次のようにしてHTML化できる。
entries.first.to_html
原稿のコンパイラは設定ファイル(bilborc)で指定する。 次のコードはHikiDocを登録する例。
require 'misc/hikidoc.rb' Entry.add_compiler('.txt') {|entry| HikiDoc.to_html(entry.body, :level => 2) }
拡張子「.txt」の原稿をHikiDocでHTML化する。
ビュー
ビューはいたってシンプル。4行で実装されている。
def render_view(name, b = binding) erb = Plugin.views[name] || (chdir(:views) { File.read("#{name}.html.erb") }) ERB.new(erb).result(b) rescue "<h3>ViewError in #{h name}</h3>#{h $!}<pre>#{$@.join("\n")}</pre>" end
HTMLテンプレートをERBにてレンダリング。
コントローラ
これも短いので、コードを全行貼ってしまったほうが話が早い。
class Controller def list @entries = Entry.find(params[:date] || '20', :limit => (params[:limit] || config[:limit] || 5).to_i, :page => (params[:page] || 0).to_i) render(:list) end def render(action) render_view(:layout) { render_view(action) } end end
デフォルトのアクションとしてlistを定義してあって、あと基本描画にレイアウトファイル(layout.html.erb)にアクション用のテンプレートを埋め込む。
そしてこのコントローラを呼び出すのが以下の部分。 CGIから渡されたactionパラメータをもとにControllerクラスに定義されているメソッドを呼び出す。
def default_action :list end def action_name # support: ruby 1.8 and 1.9 action = (params[:action] || params.index(nil) || 'list').to_sym Controller.instance_methods(false).map(&:to_sym).include?(action) ? action : default_action end def bilbo_context Plugin.load Controller.new.__send__(action_name) end
プラグインの中でControllerクラスのインスタンスメソッドを定義してやれば、 それがアクションとしてすぐに呼び出せてしまう。 よってプラグインによる機能追加かがとっても容易。