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.
Please note that Rack::Files is put before Route and Rewrite, that means that you cannot apply routes to static files unless you add your own route middleware before.
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
Class Method Details
.[](key) ⇒ Object
48 49 50 51 |
# File 'lib/innate/route.rb', line 48 def self.[](key) found = self::ROUTES.assoc(key) found[1] if found end |
.[]=(key, value) ⇒ Object
53 54 55 56 |
# File 'lib/innate/route.rb', line 53 def self.[]=(key, value) self::ROUTES.delete_if{|route_key, route_value| route_key == key } self::ROUTES << [key, value] end |
.clear ⇒ Object
58 59 60 |
# File 'lib/innate/route.rb', line 58 def self.clear self::ROUTES.clear end |
Instance Method Details
#call(env) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/innate/route.rb', line 66 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
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/innate/route.rb', line 78 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 |