lib/nyara/controller.rb in nyara-0.0.1.pre.9 vs lib/nyara/controller.rb in nyara-0.1.pre.0

- old
+ new

@@ -1,10 +1,6 @@ module Nyara - # Contain render methods - module Renderable - end - Controller = Struct.new :request class Controller module ClassMethods # #### Call-seq # @@ -13,13 +9,16 @@ # end # def http method, path, &blk @routes ||= [] @used_ids = {} + method = method.to_s.upcase action = Route.new - action.http_method = HTTP_METHODS[method] + unless action.http_method = HTTP_METHODS[method] + raise ArgumentError, "missing http method: #{method.inspect}" + end action.path = path action.set_accept_exts @formats action.id = @curr_id if @curr_id action.classes = @curr_classes if @curr_classes # todo validate arity of blk (before filters also needs arity validation) @@ -130,29 +129,25 @@ senders << "send #{method_name.inspect}, *xs\n" define_method method_name, e.blk class_eval <<-RUBY def __nyara_tmp_action *xs #{senders.join} - rescue Exception => e - handle_error e end alias :#{e.id.inspect} __nyara_tmp_action undef __nyara_tmp_action RUBY e.compile self, scope e.validate - @path_templates[e.id] = e.path_template + @path_templates[e.id] = [e.path_template, e.http_method_override] end @routes end attr_accessor :path_templates end - include Renderable - def self.inherited klass # note: klass will also have this inherited method unless klass.name.end_with?('Controller') raise "class #{klass.name} < Nyara::Controller -- class name must end with `Controller`" @@ -167,21 +162,66 @@ klass.instance_variable_set iv, value.dup end end end + def self.dispatch request, instance, args + if cookie_str = request.header._aref('Cookie') + ParamHash.parse_cookie request.cookie, cookie_str + end + request.flash = Flash.new( + request.session = Session.decode(request.cookie) + ) + + if instance + if l = Nyara.logger + l.info "#{request.http_method} #{request.path} => #{instance.class}" + end + instance.send *args + return + elsif request.http_method == 'GET' and Config['public'] + path = Config.public_path request.path + if File.file?(path) + if l = Nyara.logger + l.info "GET #{path} => public 200" + end + instance = Controller.new request + instance.send_file path + return + end + end + + if l = Nyara.logger + l.info "#{request.http_method} #{request.path} => 404" + end + Ext.request_send_data request, "HTTP/1.1 404 Not Found\r\nConnection: close\r\nContent-Length: 0\r\n\r\n" + Fiber.yield :term_close + + rescue Exception + instance.handle_error($!) if instance + end + # Path helper def path_to id, *args if args.last.is_a?(Hash) opts = args.pop end - r = self.class.path_templates[id.to_s] % args + template, meth = self.class.path_templates[id.to_s] + r = template % args if opts format = opts.delete :format r << ".#{format}" if format + if meth and !opts.key?(:_method) and !opts.key?('_method') + opts['_method'] = meth + end + elsif meth + opts = {'_method' => meth} + end + + if opts r << '?' << opts.to_query unless opts.empty? end r end @@ -208,20 +248,20 @@ def redirect url_or_path, status=302 status = status.to_i raise "unsupported redirect status: #{status}" unless HTTP_REDIRECT_STATUS.include?(status) r = request - header = r.header + header = r.response_header self.status status uri = URI.parse url_or_path if uri.host.nil? uri.host = request.domain uri.port = request.port end uri.scheme = r.ssl? ? 'https' : 'http' - r.header['Location'] = uri.to_s + header['Location'] = uri.to_s # similar to send_header, but without content-type Ext.request_send_data r, HTTP_STATUS_FIRST_LINES[r.status] data = header.serialize data.concat r.response_header_extra_lines @@ -482,10 +522,16 @@ Ext.request_wakeup request end Fiber.yield :sleep # see event.c for the handler end + # Render a template as string + def partial view_path, locals: nil + view = View.new self, view_path, nil, nil, {} + view.partial + end + # One shot render, and terminate the action. # # #### Call-seq # # # render a template, engine determined by extension @@ -543,10 +589,10 @@ # end # def handle_error e if l = Nyara.logger l.error "#{e.class}: #{e.message}" - l.error e.backtrace + l.error e.backtrace.join "\n" end status 500 send_header rescue nil # todo send body without Fiber.yield :term_close end