Normally, using PrettyURLs, there is a simple corespondence between the URL and the controller action it is routed to. But sometimes you may want to route a large swath of URLs to a single action of a single controller (referred to as the ‘default’ action of the ‘default’ controller in what follows, though there is nothing special about these names).
All you need to do is add route(s) to your config/routes.rb which will trap the URLs you want not the others (e.g. cookbook/recipies/show/42).
A simple example to capture any .php script at the root or a sub-directory of the root:
config/routes.rb
ActionController::Routing::Routes.draw do |map|
map.connect ':segment1',
:controller => 'default',
:action => 'default',
:requirements => { :segment1 => /.*\.php/ }
map.connect ':segment1/:segment2',
:controller => 'default',
:action => 'default',
:requirements => { :segment2 => /.*\.php/ }
map.connect ':controller/:action/:id'
end
Note how the routes were made specific enough that they will catch the URLs we were interested in, but not others (such as the standard :controller/:action/:id which handles the bulk of the rails URLs). If you fail to do this (e.g. if you omit the :requirements hash) all your URLs may wind up going to the new controller.
Another, less restrictive system such as the one below, which passes any URL consisting of upto four directories and a filename ending in a dot followed by three or four letters, with an optional query string can also be used. Note that this still does not conflict with the ’:controller/:action/:id’ scheme as long as none of your ids end in a dot and three or four lowercase letters.
map.connect ':file',
:controller => 'default',
:action => 'default',
:requirements => { :file => /.+\.[a-z]{3,4}/ }
map.connect ':dir1/:file',
:controller => 'default',
:action => 'default',
:requirements => { :file => /.+\.[a-z]{3,4}/ }
map.connect ':dir1/:dir2/:file',
:controller => 'default',
:action => 'default',
:requirements => { :file => /.+\.[a-z]{3,4}/ }
map.connect ':dir1/:dir2/:dir3/:file',
:controller => 'default',
:action => 'default',
:requirements => { :file => /.+\.[a-z]{3,4}/ }
map.connect ':dir1/:dir2/:dir3/:dir4/:file',
:controller => 'default',
:action => 'default',
:requirements => { :file => /.+\.[a-z]{3,4}/ }
map.connect ':controller/:action/:id'
See Rails tip: create a route with an arbitrary number of parameters for an even more generic approach that allows you to get an arbitrary number of url parameters without declaring them all in the route.
The gist of it is to use path_info in your route:
in routes.rb
...
map.connect '/category/*path_info', :controller => 'category', :action => 'list'
and in category_controller.rb
...
logger.error { "in category list, path_info = #{@params["path_info"].to_s}" }
gives the following output:
for /category/foo
in category list path_info = foo
for /category/foo/bar
in category list path_info = foo/bar