«前の日記(2005-06-15 (水)) 最新 次の日記(2005-06-17 (金))»  

まちゅダイアリー


2005-06-16 (木)

フレームワーク Sizuku

かんさんが作られた軽量フレームワークの「Nagisa」をベースにして、シンプルなフレームワークを作ってみた。 「Nagisa」にちなんで名前は「Sizuku」。 「Nagisa」と同じく、PATH_INFOでアクションを切り分けるようになっている。

Sizuku::Handlerを継承して使う感じ。サンプルは後ほど。

module Sizuku
 class Request
   def initialize(cgi)
     @cgi = cgi
     @cgi.params.each do |key, val|
       unless instance_variable_get("@#{key}")
         val = val[0] if val.size == 1
         instance_variable_set("@#{key}", val)
       end
     end
   end

   attr_reader :cgi
 end

 class Response
   def initialize(cgi)
     @header = {}
     @cgi = cgi
   end

   def set_redirect(uri)
     @header['status']   = '301 Moved Permanently'
     @header['Location'] = uri
   end

   def output(body = nil)
     print @cgi.header(@header)
     print body
   end

   attr_accessor :header
 end

 class Handler
   def initialize(conf)
   end

   def handle(cgi)
     req = Request.new(cgi)
     res = Response.new(cgi)

     if cgi.path_info =~ /\/?(.*)/
       method = $1.gsub('/','_')
     end

     method ||= 'main'
     content = __send__('handle_' + method, req, res)
     if content
       content.template_id ||= method
       content.template_path = 'template/'
       res.output(content.output)
     else
       res.output
     end
   end
 end

 # Template modules

 module BaseTemplate
   attr_accessor :template_id, :template_path

   def output
     @template_path ||= '.'
     template = "#{@template_path}/#{@template_id}"
     _output(template)
   end
 end

 begin
   require 'amrita2'
   require 'amrita2/template'
   require 'stringio'

   module Amrita2Template
     include BaseTemplate
     include Amrita2

     def _output(template)
       out = StringIO.new
       t = Amrita2::TemplateFile.new("#{template}.html")
       t.amrita_id = 'amrita_id'
       t.expand(out, self)
       out.string
     end
   end
 rescue LoadError
   # STDERR.puts 'Amrita2 is not found'
 end

 begin
   require 'erb'

   module ErbTemplate
     include BaseTemplate

     def _output(template)
       ERB.new(File.open("#{template}.rhtml"){|f| f.read}).result(binding())
     end
   end
 rescue LoadError
   # STDERR.puts 'ERB is not found'
 end
end
Tags: Ruby

フレームワーク Sizuku (2)

簡単に使い方を。

  • Sizuku::Hanlder を継承して新しいクラスを作り、「handle_アクション」のメソッドを作る。
    • ブラウザでアクセスした時のPATH_INFOに対応したアクションメソッドが実行される。デフォルトはmain。
  • アクションメソッドは、プレゼンテーションオブジェクト(後述)を返すようにする。
    • プレゼンテーションオブジェクトは、Sizuku::ErbTemplateかSizuku::Amrita2Templateをincludeしておく。
    • このオブジェクトをテンプレートファイル(アクション名.rhtml, アクション名.html)に適用させた結果が出力になる。

以下がサンプル。

index.cgi

#!/usr/bin/env ruby
require 'sizuku'

# Action Object
class MyHandler < Sizuku::Handler
  def handle_main(req, res)
    MainPage.new
  end

  def handle_sub(req, res)
    AmritaPage.new
  end
 end

# Presentation Object
class MainPage
  include Sizuku::ErbTemplate

  def text
    'hello world in erb'
  end
end

class AmritaPage
  include Sizuku::Amrita2Template

  def text
    'hello world in amrita2'
  end
end

require 'cgi'
cgi = CGI.new
MyHandler.new('sample.conf').handle(cgi)

main.rhtml

<html>
 <body>
  <p><%= text %></p>
 </body>
</html>

sub.rhtml

<html>
 <body>
 <p amrita_id='text'></p>
 </body>
</html>

上の例では、 http://example.com/index.cgi/main/ にアクセスすると handle_main が呼ばれ、 MainPage と main.rhtml を結合した結果が出力になる。

同じように、http://example.com/index.cgi/sub/ だと handle_sub が呼ばれ、 AmritaPage と sub.html を結合した結果が出力になる。

あんまり複雑なことはできないけど、ちょっとしたCGIを作る分には使えると思う。

あとは、設定ファイルの読み込みと、エラー処理の仕組みが必要だな…。

Tags: Ruby