So this has been an idea ever since Rails came out. Why not use a pure regular expression router in similar fashion to gsub? I imagine it working something like this: Merb::Router.prepare do |r| r.add %r[^/(.*)/(.*)/(\d+)$], :controller => ''\1'', :action => ''\2'', :id => ''\3'' r.add %r[^/user-(\d+)$], :user_id => ''\1'', :controller => ''free_area/users'', :action => ''index'' end The flexibility is endless in this system (far more possibilities than Rails'' system) and it lets people immediately grasp routes if then understand regular expressions (which they should, otherwise, this is a good opportunity to learn). In addition, I propose we add more options to the router so that the protocol, port, and domain become available: r.add :path => %r[^/([^\/,?]*)$], :domain => /^(blog|news) \./, :controller => ''\1'', :action => ''index'' Once this is set up, we could potentially add a convenience layer on top so that we get something a little more like our current routes: r.add ":controller/:action" # Detection of a string causes r.add to create a regexp route matching the string, e.g.: # r.add %r[^/([^/,?]+)/([^/,?]+)], :controller => ''\1'', :action => ''\2'' Thoughts? Duane Johnson (canadaduane)
On Aug 7, 2007, at 2:41 AM, Luke Sutton wrote:>> So this has been an idea ever since Rails came out. Why not use a >> pure regular expression router in similar fashion to gsub? I imagine >> it working something like this: >> >> Merb::Router.prepare do |r| >> r.add %r[^/(.*)/(.*)/(\d+)$], :controller => ''\1'', :action => >> ''\2'', :id => ''\3'' >> r.add %r[^/user-(\d+)$], :user_id => ''\1'', :controller => >> ''free_area/users'', :action => ''index'' >> end > > Certainly very powerful, but I''m a little bit dubious of it''s > usefulness ? is your intent to use regular expressions like this to > reduce redundancy in route declaration? > > In that case I think the routing DSL could be extended to make that > possible. That would be friendlier to noobs like yours truly. >I realize I''m fighting against long-held tradition. Luckily, I''m so much against the current way of things as I am deterred by its inflexibility at times (or at least, the inflexibility of Rails Routes). I feel like we should have a Pure Regex Router as the foundation, and then other router-adding styles built on top of that. Some of the things I''ve tried to do that I couldn''t: - Use symbols other than "/" to denote a partition between segments. For example: /show-user-1 /edit-movie-42 - Use specific characters to reduce the size of URLs, i.e. map url parts to other things. For example, suppose I wanted to map the CRUD + actions like this: i => index n => new c => create r => show e => edit u => update d => delete Such that the following URLs are valid: /users-i (maps to ''users'' controller, ''index'' action) /movies-u (maps to ''movies'' controller, ''update'' action) r.add %r[^/([^-]+)-([increud])$], :controller => ''\1'' do |match| map = {''i'' => ''index'', ''n'' => ''new'', ''c'' => ''create''} # etc. {:controller => match[1], :action => map[match[2]]} end - Map segments to other segments. For example, suppose you have several controllers within an admin "module", and let''s say you decide later that these controllers should be externally accessible from the "superadmin" folder as well. Currently, you would need to create a route for each controller: r.add ''/superadmin/users/:action/:id'', :controller => ''admin/users'' r.add ''/superadmin/movies/:action/:id'', :controller => ''admin/movies'' r.add ''/superadmin/categories/:action/:id'', :controller => ''admin/ categories'' etc. Instead, we should be able to do something like this: r.add ''/superadmin/:controller_segment/:action/:id'', :controller => ''admin/:controller_segment'' - Type-agnostic routing. For example, suppose I have a database of many types of objects that all share a universally unique identifier such as a GUID. By looking at the URL only, I can''t tell what the object is--so, first I need to do a database lookup to determine what type of object the referenced thing is and then route it to a controller/action pair. For example: localhost:4000/555598 r.add ''^/(\d+)$'' do |match| if obj = MyObject.find(match[1]) {:controller => obj.controller, :action => ''index''} else false end end In the above example, the router can only determine where to route to after a database lookup.>> In addition, I propose we add more options to the router so that the >> protocol, port, and domain become available: >> >> r.add :path => %r[^/([^\/,?]*)$], :domain => /^(blog|news) >> \./, :controller => ''\1'', :action => ''index'' > > Now this is a top idea! I can imagine many situations where this > would be handy. For example you might wish to route secure > connections differently. > > In addition to protocol, port and domain, it would be very useful > to have access to sub-domains in the route declarations.Yes, it would be good. Once we finish this discussion and everyone is happy with the ideas, I''ll see if I can add incorporate them into Merb. Duane
Duane Johnson
2007-Aug-08 21:19 UTC
Fwd: Proposal: Pure Regex Router (and router wishlist)
Forgot to reply to list. ---------- Forwarded message ---------- From: Duane Johnson <canadaduane at gmail.com> Date: Aug 8, 2007 3:17 PM Subject: Re: Proposal: Pure Regex Router (and router wishlist) To: Daniel N <has.sox at gmail.com> I realize I''m fighting against long-held tradition. Luckily, I''m so> much against the current way of things as I am deterred by its > inflexibility at times (or at least, the inflexibility of Rails > Routes). I feel like we should have a Pure Regex Router as the > foundation, and then other router-adding styles built on top of that. > >Correction: The above should read, "I''m *not* so much against the current way of things, as I am deterred by its inflexibility at times." Sorry about the harsh sounding original text. On 8/7/07, Daniel N <has.sox at gmail.com> wrote:> > > > I''m not sure why you would want the above in any routes. Merb supports > restful routes so I don''t see why you would want what you suggested there. > > You end up mixing the verb into the noun and get multiple url''s for a > resourse just to do crud. That''s what restful routes gets us away from. > Personally I like the restful conventions and find that it does nice things > to the way I think of stuff. >Agreed. I see that it was not a very convincing example, but the point was to show how an idea outside the box is currently "impossible" without rewriting the router. My objective is to find a solution with the fewest possible restrictions (a superset) so that the current best-practice ( i.e. restful routes and rails-alike routes) becomes a subset of the solution. The other two examples, map segments to other segments, and type agnostic> routing look interesting to me though. >Just my 0.02>Thanks for your feedback on these. Duane Johnson (canadaduane) -------------- next part -------------- An HTML attachment was scrubbed... URL: rubyforge.org/pipermail/merb-devel/attachments/20070808/0fe29115/attachment.html