module Nitro # Router mixin. Typically used to generate 'nice' urls. # Nice urls apart from looking more beautiful are considered (?) # more Search Engine friendly. # # However, due to the power of Nitro's intelligent dispatching # mechanism, routing is almost never used! It is only needed # for really special urls. # # === Example # # can also be initialized by a YAML file through Configuration. # # Router.rules = [ # {:match => /rewritten\/url\/(.*)/, :controller => IdController, :action => :register, :param => :name}, # {:match => %r{another/zelo/(.*)/(.*)}, :controller => AdminController, :action => :kick, :params => [:name, :age]} # ] # # or # # Router.add_rule :match => /rewritten\/url\/(.*)/, :controller => IdController, :action => :register, :param => :name # Router.add_rule :match => %r{another/zelo/(.*)/(.*)}, :controller => AdminController, :action => :kick, :params => [:name, :age] # # this is the global table that initializes each Router # instance. # # or (specialized per Router instance) # # r.add_rule(:match => %r{rewritten/url/(.*)}, :controller => IdController, :action => :register, :param => :name) # r.add_rule(:match => %r{another/zelo/(.*)/(.*)}, :controller => AdminController, :action => :kick, :params => [:name, :age]) # r.add_rule(:match => %r{cool/(.*)_(.*).html}, :controller => AdminController, :action => :long, :params => [:name, :age]) # #-- # gmosx, TODO: use a hash only instead of [rule, options] #++ module Router # Strip the beginning of the path, used by cgi adapter. setting :strip_path, :default => nil, :doc => 'Strip the beginning of the path, used by cgi adapter' # The routing rules. The rules in this table are used to initialize # the routing table of each instantiated router. setting :rules, :default => [], :doc => 'The routing rules' # The rules map 'nice URLs' to real URLs that # can be handled by the Dispatcher. attr_accessor :rules # Initialize the routing table by importing from the global # Router rules. def init_routes @rules = Router.rules.dup end # Decodes a url to a [controller, action, params] tupple. # Returns false if no decoding is possible. def decode_route(url) for rule in @rules if md = url.match(rule[:match]) params = nil if param_names = rule[:params] || rule[:param] param_names = [ param_names ] unless param_names.is_a?(Array) params = {} md.captures.each_with_index do |val, idx| params[param_names[idx].to_s] = val end end Logger.debug "Rewriting '#{url}' to '#{rule[:controller]}##{rule[:action]}(#{params.values.join(', ')})." if $DBG return rule[:controller], rule[:action], params end end return false end alias_method :route, :decode_route # Encodes a [controller, action, params] tupple into a url. # Returns false if no encoding is possible. def encode_route(controller, action, *params) if rule = @rules.find { |r| (r[:controller] == controller) and (r[:action] == action) } url = rule[:match].source (params.size / 2).times do |i| val = params[i + i + 1] url.sub!(/\(.*?\)/, val.to_s) end return url end return false end # Add a route to the routing table. def add_rule(rule) @rules << rule end alias_method :<<, :add_rule def add_rules(new_rules) @rules.concat(new_rules) end class << self def add_rule(rule) self.rules << rule end alias_method :<<, :add_rule end end end # * George Moschovitis