Parent

Picombo::Router

Processes the URI to route requests to proper controller

Using Routes

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:

Using lambdas for routes

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
 })

Route Hashes

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.

Public Class Methods

add(key, val, style = nil) click to toggle source

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
controller() click to toggle source

Reads the current controller of the request

    # File lib/classes/router.rb, line 63
63:         def self.controller
64:             @@controller
65:         end
controller=(controller) click to toggle source

Assigns the current controller of the request

    # File lib/classes/router.rb, line 59
59:         def self.controller=(controller)
60:             @@controller = controller
61:         end
current_uri() click to toggle source

Reads the current uri of the request

    # File lib/classes/router.rb, line 43
43:         def self.current_uri
44:             @@current_uri
45:         end
current_uri=(current_uri) click to toggle source

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
generate(key, params = []) click to toggle source

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
method() click to toggle source

Reads the current method of the request

    # File lib/classes/router.rb, line 71
71:         def self.method
72:             @@method
73:         end
method=(method) click to toggle source

Assigns the current method of the request

    # File lib/classes/router.rb, line 67
67:         def self.method=(method)
68:             @@method = method
69:         end
new(req) click to toggle source

Initializes the request

    # File lib/classes/router.rb, line 76
76:         def initialize(req)
77:             @@req = req
78:         end
process_uri(path) click to toggle source

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
rsegments=(rsegments) click to toggle source

Assigns the current rsegments of the request

    # File lib/classes/router.rb, line 55
55:         def self.rsegments=(rsegments)
56:             @@rsegments = rsegments
57:         end
segments() click to toggle source

Reads the current segments of the request

    # File lib/classes/router.rb, line 51
51:         def self.segments
52:             @@segments
53:         end
segments=(segments) click to toggle source

Assigns the current segments of the request

    # File lib/classes/router.rb, line 47
47:         def self.segments=(segments)
48:             @@segments = segments
49:         end

Public Instance Methods

process() click to toggle source

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.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.