Class: Racket::Router
- Inherits:
-
Object
- Object
- Racket::Router
- Defined in:
- lib/racket/router.rb
Overview
Handles routing in Racket applications.
Instance Method Summary collapse
-
#cache_actions(controller) ⇒ nil
Caches available actions for each controller class.
-
#get_route(controller, action, params) ⇒ String
Returns a route to the specified controller/action/parameter combination.
-
#initialize ⇒ Router
constructor
A new instance of Router.
-
#map(path, controller) ⇒ nil
Maps a controller to the specified path.
-
#render_error(status, error = nil) ⇒ Object
@todo: Allow the user to set custom handlers for different errors.
-
#route(env) ⇒ Array
Routes a request and renders it.
Constructor Details
#initialize ⇒ Router
Returns a new instance of Router.
26 27 28 29 30 |
# File 'lib/racket/router.rb', line 26 def initialize @router = HttpRouter.new @routes_by_controller = {} @actions_by_controller = {} end |
Instance Method Details
#cache_actions(controller) ⇒ nil
Caches available actions for each controller class. This also works for controller classes that inherit from other controller classes.
37 38 39 40 41 42 43 44 45 46 |
# File 'lib/racket/router.rb', line 37 def cache_actions(controller) actions = Set.new current = controller while current < Controller actions.merge(current.instance_methods(false)) current = current.superclass end @actions_by_controller[controller] = actions.to_a nil end |
#get_route(controller, action, params) ⇒ String
Returns a route to the specified controller/action/parameter combination.
54 55 56 57 58 59 60 61 62 |
# File 'lib/racket/router.rb', line 54 def get_route(controller, action, params) route = '' route << @routes_by_controller[controller] if @routes_by_controller.key?(controller) action = action.to_s route << "/#{action}" unless action.empty? route << "/#{params.join('/')}" unless params.empty? route = route[1..-1] if route.start_with?('//') # Special case for root path route end |
#map(path, controller) ⇒ nil
Maps a controller to the specified path.
69 70 71 72 73 74 75 76 |
# File 'lib/racket/router.rb', line 69 def map(path, controller) controller_base_path = path.empty? ? '/' : path Application.inform_dev("Mapping #{controller} to #{controller_base_path}.") @router.add("#{path}(/*params)").to(controller) @routes_by_controller[controller] = controller_base_path cache_actions(controller) nil end |
#render_error(status, error = nil) ⇒ Object
@todo: Allow the user to set custom handlers for different errors
79 80 81 82 83 84 85 86 87 |
# File 'lib/racket/router.rb', line 79 def render_error(status, error = nil) # If running in dev mode, let Rack::ShowExceptions handle the error. raise error if error && Application.dev_mode? # Not running in dev mode, let us handle the error ourselves. response = Response.new([], status, { 'Content-Type' => 'text/plain' }) response.write("#{status} #{Rack::Utils::HTTP_STATUS_CODES[status]}") response.finish end |
#route(env) ⇒ Array
Routes a request and renders it.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/racket/router.rb', line 93 def route(env) begin catch :response do # Catches early exits from Controller.respond. # Find controller in map # If controller exists, call it # Otherwise, send a 404 matching_routes = @router.recognize(env) unless matching_routes.first.nil? target_klass = matching_routes.first.first.route.dest params = matching_routes.first.first.param_values.first.reject { |e| e.empty? } action = params.empty? ? target_klass.get_option(:default_action) : params.shift.to_sym # Check if action is available on target return render_error(404) unless @actions_by_controller[target_klass].include?(action) # Initialize target target = target_klass.new # @fixme: File.dirname should not be used on urls! 1.upto(params.count) do env['PATH_INFO'] = File.dirname(env['PATH_INFO']) end target.extend(Current.init(env, action, params)) target.render(action) else render_error(404) end end rescue => err render_error(500, err) end end |