レンタルサーバで rails 使えなくても 、同じ url ルールで mvc したい。
ちょっと機能追加して簡易掲示板を作ってみた。
ディレクトリ構成
gup.cgi + app + contollers + board.rb + views + board + index.rhtml + data + board.log
dispatcher - gup.cgi
#!/usr/bin/ruby -Ku require 'cgi' require 'cgi/session' require 'cgi/session/pstore' require 'erb' CONTROLLER_PATH = "app/controllers/" VIEW_PATH = "app/views/" class GupDispatchError < StandardError ; end class GupBase def puts(msg) $stderr.puts msg end def escape(html) CGI.escapeHTML(html) end def render(option={}) @__gup_render_option__ = option end def redirect_to(option={}) @__gup_recirect_option__ ||= option end def __response__(cgi , category , action) if @__gup_recirect_option__ action = @__gup_recirect_option__[:action] || action url = cgi.script_name.split[0] + "/" + category url << "/" + action if action != "index" print cgi.header({'status' => '302 Found', 'Location' => url }) else @__gup_render_option__ ||= {} action = @__gup_render_option__[:action] || action path = VIEW_PATH + category + "/" + action + ".rhtml" begin cgi.out({ "type" => "text/html", "charset" => "utf-8", "connection" => "close", }){ ERB.new(open(path){|f| f.read}).result(binding) } rescue Errno::ENOENT => e e.to_s end end end end def create_session(cgi) CGI::Session::new(cgi , { "database_manager" => CGI::Session::PStore , "prefix" => "gup_" , "tmpdir" => "/tmp" }) end def dispatch(cgi , session) info = cgi.path_info.split("/") raise GupDispatchError.new "welcome to gup" if info.length == 0 info[2] = "index" if info.length < 3 || !info[2] begin load CONTROLLER_PATH + info[1] + ".rb" #require CONTROLLER_PATH + info[1] rescue LoadError => e raise GupDispatchError.new "unknown => #{info[1].capitalize}##{info[2]}" end app = eval(info[1].capitalize + ".new") raise GupDispatchError.new "#{info[1].capitalize} must extends GupBase" unless app.kind_of? GupBase app.instance_variable_set("@params" , cgi.params) app.instance_variable_set("@session" , session) begin app.__send__(info[2]) rescue NoMethodError => e raise GupDispatchError.new "unknown #{info[1].capitalize}##{info[2]}" end app.__response__(cgi , info[1] , info[2]) end cgi = CGI.new session = create_session(cgi) begin dispatch(cgi , session) rescue GupDispatchError => e cgi.out({"type"=>"text/html","charset"=>"utf-8","connection"=>"close"}){e.to_s} end exit
controller - board.rb
class Board < GupBase def index begin @list = open("data/board.log") {|f| f.read.split("\n")}.reverse rescue Errno::ENOENT @list = [] end end def post name = @params["name"][0] email = @params["email"][0] comment = @params["comment"][0] if name.length != 0 && email.length != 0 && comment.length != 0 open("data/board.log" , "a"){|f| f.puts name + "," + email + "," + comment } end redirect_to :action => "index" end end
view - index.rhtml
<% def escape(msg) msg ? CGI.escapeHTML(msg) : "" end %> <html> <head><title>board</title></head> <body> <form action="/gup/board/post" method="post"> <table> <tr><td>name </td><td><input type="text" name="name" size="50"></td></tr> <tr><td>email </td><td><input type="text" name="email" size="50"></td></tr> <tr><td>comment</td><td><input type="text" name="comment" size="100"></td></tr> </table> <input type="submit" value="submit"> </form> <hr> <% for i in 0...(@list.length < 10 ? @list.length : 10) info = @list[i].split(",") %> <span style="background-color:#C8E3FF;padding:1"><%= escape(info[0]) %> - <%= escape(info[1]) %></span><br> <%= escape(info[2]) %> <hr> <% end %> </body> </html>