On Fri, Jan 29, 2010 at 10:07 AM, Jonathan Vanasco
<[email protected]> wrote:
> using Routes 1.10 and 1.11 ...
>
> 1) how can i match to a single controller's
> /admin - def index
> /admin/ - def index
> /admin/$action$ - def $action
This requires three routes. Normally you wouldn't define /action/, or
if you did, you'd make it redirect to /action, so that you don't have
multiple URLs for the same thing. Routes now has redirect routes, so
you can do the latter without making a dummy action for it.
Routes used to have minimization, where the user could leave off the
rightmost URL components and they'd be supplied by default values or
implicit defaults. This would allow you to combine the second and
third routes. It still does if you set map.minimization=True, but
minimization turned out to cause hard-to-trace bugs when a route
unexpectedly matched a URL it wasn't intended to. So now every part of
the route path has to match, and thus you need a separate route if you
want to match a shorter URL. This leads to more route definitions, but
it makes it more predictable which route will match which URL.
> must i do this explicitly in two calls ? because
> /admin/{action} requires the /
With {action} there's no way around it. With another variable, there
could be. "{varname:.*}" will match all characters including a slash,
and thus the rest of the URL. Your action could strip the
leading/trailing slashes to extract a usable value. But this doesn't
work for "{action}" because the method name has to be known -- without
slashes -- before your action starts executing.
Actually, there is another way. If you define a function condition
(http://routes.groovie.org/manual.html#setting-up-routes), you can
manipulate the variable values before the match decision is decided.
The following is an untested guess:
def myfunc(environ, match_dict):
action = match_dict["action"].strip() # Strip leading/trailing slash.
if not action:
action = "index" # Default to "index" if no action specified/
match_dict["action"] = action
return True # Tell Routes that this route successfully matched the URL.
map.connect("admin", "/admin{action:.*}", conditions={"func": myfunc})
This would work for "/admin/" and "/admin/myaction". It may or may
not work for "/admin". Normally a ".*" regex will match an empty
string, but I'm not sure if Routes does something extra to prevent it.
Note that this route would also match "/administration" and
"/admin123"! That's why you normally put slashes outside path
variables, to prevent "/adminOopsIDidn'tIntendThis" from matching.
> 2) is it possible to use the {action} as a string component of the
> action name ? or would i have to make a custom routes implementation..
> or dispatch to a method that can re-dispatch within the controller
> i.e.
> /error/{action} -> def error__$action$
You can do that with a function as above.
action = "error__" + action
By the way, a "filter function" is the reverse, to convert url()
variables during generation.
I consider such slash manipulation to be highly unorthodox and
undesirable, but that's how you can do it if you want to.
--
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.