Object
Processes the URI to route requests to proper controller
Routes are defined in the config/routes.rb config file.
There should always be a ‘_default’ route, which is the route that applies when there are no uri segments. ex: +Picombo::Router.add(‘_default’, ‘controller/method’)+
The first kind of route is an exact match route. This will look for a URI match in the keys of the routes file. ex: +Picombo::Router.add(‘foobar/baz’, ‘controller/method’)+
You can also use regex routes for more powerful routing:
A catch-all route: Picombo::Router.add(Regexp.new(/(.+)/), ‘controller/method’)
Routing all second URI segments to the index method: Picombo::Router.add(Regexp.new(/foobar/(.+)/), ‘foobar/index’)
Picombo::Router.add(Regexp.new(/([a-z]{2})/), ‘chamber/video/\1’)
You can use lamba methods for complex routing schemes that rely on extra logic. The first parameter to the lambda method is the source uri as a string
Picombo::Route.add('my complex route', lambda{ |path|
if Regexp.new('(complex|foobar)/([a-z]{2})/(.+)').match(path)
{:controller => 'city', :method => 'index', :params => Regexp.last_match[2,3]}
end
})
The router uses route hashes as shown above to determine which controller/method should be run. It has the following properties:
:controller - The controller name to execute :method - The method of the controller to run :param - The parameters to pass to the controller method
If you use lambda routes, you must return a properly formatted routing hash.
Adds a route to the router
key - the name of the route (optionally the source URI for simple routes)
val - the destination of the route (optionally a lambda for complex routes)
# File lib/classes/router.rb, line 141
141: def self.add(key, val, style = nil)
142: @@routes[key] = {:val => val, :generate => style}
143: end
Reads the current controller of the request
# File lib/classes/router.rb, line 63
63: def self.controller
64: @@controller
65: end
Assigns the current controller of the request
# File lib/classes/router.rb, line 59
59: def self.controller=(controller)
60: @@controller = controller
61: end
Reads the current uri of the request
# File lib/classes/router.rb, line 43
43: def self.current_uri
44: @@current_uri
45: end
Assigns the current uri of the request
# File lib/classes/router.rb, line 39
39: def self.current_uri=(current_uri)
40: @@current_uri = current_uri
41: end
Generates a routed URI based on paramaters
# File lib/classes/router.rb, line 146
146: def self.generate(key, params = [])
147: raise ArgumentError.new('The route: "'+key+'" doesn\t exist!') if ! @@routes.key?(key)
148: route = @@routes[key]
149:
150: routing_string = route[:generate]
151:
152: params.each do |key, value|
153: routing_string.gsub!('{'+key.to_s+'}', value)
154: end
155:
156: routing_string
157: end
Reads the current method of the request
# File lib/classes/router.rb, line 71
71: def self.method
72: @@method
73: end
Assigns the current method of the request
# File lib/classes/router.rb, line 67
67: def self.method=(method)
68: @@method = method
69: end
Initializes the request
# File lib/classes/router.rb, line 76
76: def initialize(req)
77: @@req = req
78: end
Takes a uri path string and determines the controller, method and any get parameters Uses the routes config file for translation
# File lib/classes/router.rb, line 161
161: def self.process_uri(path)
162:
163: # Load routes
164: Picombo::Core.find_file('config', 'routes').each do |file|
165: require file
166: end
167:
168: router_parts = path == '/' ? ('/'+@@routes['_default'][:val]).split('/') : path.split('/')
169: @@current_uri = path.split('?').at(0)
170: @@current_uri.slice!(0)
171: @@segments = @@current_uri.split('/')[1..1]
172: @@rsegments = router_parts[1..1]
173: routed_uri = @@current_uri
174:
175: # Try and find a direct match
176: if @@routes.key?(@@current_uri)
177: routed_uri = @@routes[@@current_uri][:val]
178: @@rsegments = routed_uri.split('/')
179: else
180: @@routes.each do |route, destination|
181: if destination[:val].is_a?(Proc)
182: route = destination[:val].call(@@current_uri)
183: return route if ! route.nil?
184: elsif route.is_a?(Regexp)
185: match = route.match(@@current_uri)
186: if ! match.nil? and match.length > 1
187: routed_uri.gsub!(route, destination[:val])
188: @@rsegments = routed_uri.split('/')
189: end
190: end
191: end
192: end
193:
194: params = @@rsegments.slice(2, router_parts.length)
195:
196: if ! params.nil?
197: params.collect! do |param|
198: param.split('?').at(0)
199: end
200: else
201: params = []
202: end
203:
204: # Use the default route if nothing has been found
205: if ! @@rsegments[1].nil?
206: @@rsegments[1] = @@rsegments[1].split('?').at(0)
207: else
208: @@rsegments[1] = ('/'+@@routes['_default'][:val]).split('/').at(2)
209: end
210:
211: # make sure to remove the GET from any of the parameters
212: {:controller => @@rsegments[0].split('?').at(0).gsub('.', '').downcase, :method => @@rsegments[1], :params => params}
213: end
Assigns the current rsegments of the request
# File lib/classes/router.rb, line 55
55: def self.rsegments=(rsegments)
56: @@rsegments = rsegments
57: end
Processes the URI
# File lib/classes/router.rb, line 81
81: def process()
82: Picombo::Bench.instance.start('setup')
83:
84: Picombo::Event.run('system.pre_router')
85: # Find the controller and method
86: uri = @@req.path
87: uri = Picombo::Router.process_uri(uri)
88:
89: # Let events have the ability to modify the uri array
90: Picombo::Event.run('system.post_router', uri)
91: @@controller = 'Picombo::Controllers::'+uri[:controller]
92: @@method = uri[:method]
93:
94: # Try and load the controller class
95: begin
96: controller = Picombo::Controllers::const_get(uri[:controller].capitalize!).new
97: rescue LoadError, NameError => e
98: puts 'LoadError or NameError: '+e.message
99: return Picombo::Controllers::Error_404.new.run_error(@@req.path)
100: end
101:
102: controller_methods = controller.methods
103:
104: Picombo::Bench.instance.stop('setup')
105:
106: # Execute the controller method
107: Picombo::Bench.instance.start('controller_execution')
108:
109: Picombo::Event.run('system.pre_controller')
110: begin
111: if ! controller_methods.include?(uri[:method].to_sym) and ! controller_methods.include?(uri[:method].to_s)
112: raise Picombo::E404
113: end
114:
115: if uri[:params].nil? or uri[:params].empty?
116: controller.send(uri[:method])
117: else
118: controller.send(uri[:method], *uri[:params])
119: end
120: rescue ArgumentError => e
121: puts 'ArgumentError 404: '+e.message
122: puts e.backtrace
123: return Picombo::Controllers::Error_404.new.run_error(@@req.path)
124: rescue Picombo::E404 => e
125: puts '404 Error: '+e.message
126: puts e.backtrace
127: return Picombo::Controllers::Error_404.new.run_error(@@req.path)
128: end
129: Picombo::Event.run('system.post_controller')
130:
131: Picombo::Bench.instance.stop('controller_execution')
132: Picombo::Bench.instance.stop('application')
133:
134: Picombo::Core.render
135: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.