Class: Innate::Route
- Inherits:
-
Object
- Object
- Innate::Route
- Defined in:
- lib/innate/route.rb
Overview
Innate support simple routing using string, regex and lambda based routers. Route are stored in a dictionary, which supports hash-like access but preserves order, so routes are evaluated in the order they are added.
This middleware should wrap Innate::DynaMap.
String routers are the simplest way to route in Innate. One path is translated into another:
Innate::Route[ '/foo' ] = '/bar'
'/foo' => '/bar'
Regex routers allow matching against paths using regex. Matches within your regex using () are substituted in the new path using printf-like syntax.
Innate::Route[ %r!^/(\d+)\.te?xt$! ] = "/text/%d"
'/123.txt' => '/text/123'
'/789.text' => '/text/789'
For more complex routing, lambda routers can be used. Lambda routers are passed in the current path and request object, and must return either a new path string, or nil.
Innate::Route[ 'name of route' ] = lambda{ |path, request|
'/bar' if path == '/foo' and request[:bar] == '1'
}
'/foo' => '/foo'
'/foo?bar=1' => '/bar'
Lambda routers can also use this alternative syntax:
Innate::Route('name of route') do |path, request|
'/bar' if path == '/foo' and request[:bar] == '1'
end
NOTE: Use self::ROUTES notation in singleton methods to force correct
lookup.
Direct Known Subclasses
Constant Summary collapse
- ROUTES =
[]
Class Method Summary collapse
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app = Innate::DynaMap) ⇒ Route
constructor
A new instance of Route.
- #resolve(path) ⇒ Object
Constructor Details
#initialize(app = Innate::DynaMap) ⇒ Route
Returns a new instance of Route.
58 59 60 |
# File 'lib/innate/route.rb', line 58 def initialize(app = Innate::DynaMap) @app = app end |
Class Method Details
.[](key) ⇒ Object
44 45 46 47 |
# File 'lib/innate/route.rb', line 44 def self.[](key) found = self::ROUTES.assoc(key) found[1] if found end |
.[]=(key, value) ⇒ Object
49 50 51 52 |
# File 'lib/innate/route.rb', line 49 def self.[]=(key, value) self::ROUTES.delete_if{|k,v| k == key } self::ROUTES << [key, value] end |
.clear ⇒ Object
54 55 56 |
# File 'lib/innate/route.rb', line 54 def self.clear self::ROUTES.clear end |
Instance Method Details
#call(env) ⇒ Object
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/innate/route.rb', line 62 def call(env) path = env['PATH_INFO'] path << '/' if path.empty? if modified = resolve(path) Log.debug("%s routes %p to %p" % [self.class.name, path, modified]) env['PATH_INFO'] = modified end @app.call(env) end |
#resolve(path) ⇒ Object
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/innate/route.rb', line 74 def resolve(path) self.class::ROUTES.each do |key, value| if key.is_a?(Regexp) md = path.match(key) return value % md.to_a[1..-1] if md elsif value.respond_to?(:call) new_path = value.call(path, Current.request) return new_path if new_path elsif value.respond_to?(:to_str) return value.to_str if path == key else Log.error("Invalid route %p => %p" % [key, value]) end end nil end |