lib/roda/plugins/multi_route.rb in roda-0.9.0 vs lib/roda/plugins/multi_route.rb in roda-1.0.0
- old
+ new
@@ -1,41 +1,58 @@
class Roda
module RodaPlugins
# The multi_route plugin allows for multiple named routes, which the
- # main route block can dispatch to by name at any point. If the named
- # route doesn't handle the request, execution will continue, and if the
- # named route does handle the request, the response by the named route
- # will be returned.
+ # main route block can dispatch to by name at any point by calling +route+.
+ # If the named route doesn't handle the request, execution will continue,
+ # and if the named route does handle the request, the response returned by
+ # the named route will be returned.
#
+ # In addition, this also adds the +r.multi_route+ method, which will assume
+ # check if the first segment in the path matches a named route, and dispatch
+ # to that named route.
+ #
# Example:
#
# plugin :multi_route
#
- # route(:foo) do |r|
+ # route('foo') do |r|
# r.is 'bar' do
# '/foo/bar'
# end
# end
#
- # route(:bar) do |r|
+ # route('bar') do |r|
# r.is 'foo' do
# '/bar/foo'
# end
# end
#
# route do |r|
+ # r.multi_route
+ #
+ # # or
+ #
# r.on "foo" do
- # route :foo
+ # r.route 'foo'
# end
#
# r.on "bar" do
- # route :bar
+ # r.route 'bar'
# end
# end
#
# Note that in multi-threaded code, you should not attempt to add a
# named route after accepting requests.
+ #
+ # If you want to use the +r.multi_route+ method, use string names for the
+ # named routes. Also, you can provide a block to +r.multi_route+ that is
+ # called if the route matches but the named route did not handle the
+ # request:
+ #
+ # r.multi_route do
+ # "default body"
+ # end
module MultiRoute
# Initialize storage for the named routes.
def self.configure(app)
app.instance_exec{@named_routes ||= {}}
end
@@ -45,10 +62,15 @@
def inherited(subclass)
super
subclass.instance_variable_set(:@named_routes, @named_routes.dup)
end
+ # An names for the currently stored named routes
+ def named_routes
+ @named_routes.keys
+ end
+
# Return the named route with the given name.
def named_route(name)
@named_routes[name]
end
@@ -62,13 +84,31 @@
super(&block)
end
end
end
- module InstanceMethods
+ module RequestClassMethods
+ # A regexp matching any of the current named routes.
+ def named_route_regexp
+ @named_route_regexp ||= /(#{Regexp.union(roda_class.named_routes)})/
+ end
+ end
+
+ module RequestMethods
+ # Check if the first segment in the path matches any of the current
+ # named routes. If so, call that named route. If not, do nothing.
+ # If the named route does not handle the request, and a block
+ # is given, yield to the block.
+ def multi_route
+ on self.class.named_route_regexp do |section|
+ route(section)
+ yield if block_given?
+ end
+ end
+
# Dispatch to the named route with the given name.
def route(name)
- instance_exec(request, &self.class.named_route(name))
+ scope.instance_exec(self, &self.class.roda_class.named_route(name))
end
end
end
register_plugin(:multi_route, MultiRoute)