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