module Roda::RodaPlugins::MultiRoute

  1. lib/roda/plugins/multi_route.rb

The multi_route plugin allows for multiple named routes, which the 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 plugin adds the r.multi_route method, which will 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|
  r.is 'bar' do
    '/foo/bar'
  end
end

route('bar') do |r|
  r.is 'foo' do
    '/bar/foo'
  end
end

route do |r|
  r.multi_route

  # or

  r.on "foo" do
    r.route 'foo'
  end

  r.on "bar" do
    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

If a block is not provided to multi_route, the return value of the named route block will be used.

Routing Files

The convention when using the multi_route plugin is to have a single named route per file, and these routing files should be stored in a routes subdirectory in your application. So for the above example, you would use the following files:

routes/bar.rb
routes/foo.rb

Namespace Support

The multi_route plugin also has support for namespaces, allowing you to use r.multi_route at multiple levels in your routing tree. Example:

route('foo') do |r|
  r.multi_route('foo')
end

route('bar') do |r|
  r.multi_route('bar')
end

route('baz', 'foo') do |r|
  # handles /foo/baz prefix
end

route('quux', 'foo') do |r|
  # handles /foo/quux prefix
end

route('baz', 'bar') do |r|
  # handles /bar/baz prefix
end

route('quux', 'bar') do |r|
  # handles /bar/quux prefix
end

route do |r|
  r.multi_route

  # or

  r.on "foo" do
    r.on("baz"){r.route("baz", "foo")}
    r.on("quux"){r.route("quux", "foo")}
  end

  r.on "bar" do
    r.on("baz"){r.route("baz", "bar")}
    r.on("quux"){r.route("quux", "bar")}
  end
end

Routing Files

The convention when using namespaces with the multi_route plugin is to store the routing files in subdirectories per namespace. So for the above example, you would have the following routing files:

routes/bar.rb
routes/bar/baz.rb
routes/bar/quux.rb
routes/foo.rb
routes/foo/baz.rb
routes/foo/quux.rb

Methods

Public Class

  1. configure

Public Class methods

configure (app)

Initialize storage for the named routes.

[show source]
# File lib/roda/plugins/multi_route.rb, line 129
def self.configure(app)
  app.opts[:namespaced_routes] ||= {}
  app::RodaRequest.instance_variable_set(:@namespaced_route_regexps, {})
end