On Sat, Mar 8, 2008 at 10:05 AM, Jose Galvez <[EMAIL PROTECTED]> wrote:
>
>
>
>  Mike Orr wrote:
>
>  On Fri, Mar 7, 2008 at 12:51 PM, Poli García <[EMAIL PROTECTED]> wrote:
>
>
>  Hi !
>  I'm having an issue with URL parameters. I have these routes mapped on
> my routing.py:
>
>
>
>  map.connect('/a_url_path/:param1/:param2', controller='some_controller',
>
>  action='an_action')
>
>
>  map.connect('/another_url_path/', controller='some_controller',
>
>  action='another_action')
>
> and some_controller.an_action defined as:
>
>
>
>  def an_action(self, param1, param2):
>  # Some work with param1 and param2
>  return render('/some_template.mako')
>
>  On some_template.mako I have an anchor defined as:
>
>
>
>  ${h.link_to('A Link', h.url_for(controller='some_controller',
>
>  action='another_action'))}
>
>  The problem occurs when I navigate to /a_url_path/a_value/another_value.
> The
> link on the page is rendered as
> /another_url_path?param1=a_value&param2=another_value. It's like all URL
> parameters are propagated to the links. This doesn't happen always.. and I
> cannot figure out the occurrence pattern. If I name the second route and
> create the link using the name of the route, the parameters are not
> propagated.
>
> Can someone tell me how to avoid this?
>
>  The Routes algorithms are too complex and occasionally lead to
> situations like this. Your best bet is to use named routes, but even
> that can fail sometimes. The problem is that 'another_url_path' has
> no variables in it, so url_for is choosing it when it shouldn't. When
> I've encountered this -- mainly with links to static files -- I've
> just tried different things till it works, or used hardcoded URLs if
> it just won't.
>
> Routes 2 will simplify the algorithms greatly, and probably require
> all routes and url_for calls to use route names, so that should
> eliminate this problem in a couple months. You will have to change
> your routing rules so be prepared. (Although you'll be able to stick
> with Routes 1 if you're happy with your current routing rules.)
>
>  I hope not, I would hate to have to name all my routes, especially when
> controller=foo, action=bar  is much more informative then a route named
> fooBar

That only works due to variable matching ; i.e., it chooses the route
with the highest number of common variables between the route
definitions and the values supplied.  This is an imprecise algorithm
that sometimes chooses the wrong route, which is why url_for sometimes
spits out a URL that's not even close to correct.  Variable matching
and minimization make Routes a pain to write unit tests for and debug.
 So the goal of Routes 2 is to make it much more straightforward and
deterministic.

There's another problem with url_for(controller="foo", action="bar")
in that it makes the URLs and controller/action names dependent on
each other, which defeats the purpose of Routes.  Other frameworks
have a built-in dispatcher that maps a URL to an action with a certain
name.  Routes exists to let you restructure your URLs independently
from your controllers/actions and vice-versa, and then change the
connections between the two.  With named routes this works seamlessly
and all the url_for calls remain valid.  But url_for(controller="foo",
action="bar") assumes there's a route ":controller/:action" and a
class 'Controller' with method 'action'.  If you change either the URL
path or the controller name or action name, the url_for call breaks
and you have to go changing url_for calls all over your application.

You don't name routes "fooBar" to match the controller/action; you
give them some kind of semantic name.  If it's a FAQ section, name it
"faq" -- regardless of what the URL or action name is.  If it's
article 15 in the platypus section, name it "platypus_article" or
"animal_article".  Something that's globally unique and comprehensible
on its own.

Having said that, url_for(controller="foo", action="bar") may be
supported with a default route.  We're still going back and forth on
that.  But the idea is you would define a special route
(":controller/:action") in this context) which would be tried last
during matching; i.e., if all the named routes fail.  Conversely, a
separate url_for method would choose the default route.  So instead of
url_for.name(**variables), you would do url_for(**variables), and it
would consider only the default route.

To truly do what you want -- "Return the URL for controller 'foo'
action 'bar', no matter which route it is -- would require a separate
route index keyed by (controller, action).  That's possible but it
would require some infrastructure we hadn't intended.  I'll think
about it.  One issue is it ties Routes to Pylons conventions
('controller' and 'action'), while we were trying to make it
framework-neutral.  Maybe Routes needs a neutral base class and Pylons
subclass.

-- 
Mike Orr <[EMAIL PROTECTED]>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to