Help converting Pylons {name}{.format} style routes to Pyramid

21 views
Skip to first unread message

Andrew McNamara

unread,
Mar 20, 2018, 12:37:22 AM3/20/18
to pylons-discuss
I have a large Pylons app that I'm considering converting to Pyramid. My main difficulty is the existing app uses Pylons routes like /something/{name}{.format} extensively. I have considered expanding the {.format} part into something like {format:\.[a-z]+}, however the Pylons route also matches URLs with no extension (eg /something/name). A more conditional pattern like {format:(\.[a-z]+)?} has nothing to anchor to, so the {name} part claims the whole string. The only other option I can think of is to duplicate the routes (and the view_config), however the application has about 300 routes already, so this would be painful and ugly. Cleaning up the API presented by the application is also not viable - I don't control all the client code. At this stage, I'm considering implementing a view_config replacement that autogenerates routes (hiding the painful and ugly). Does anyone have any better suggestions?

Jonathan Vanasco

unread,
Mar 22, 2018, 2:34:36 PM3/22/18
to pylons-discuss
There's also some pyramid docs on predicates and route factory under URL dispatch.   I think that might be what you need - there are some threads in this group on those topics.

I also wrote a library `pyramid_route_7` (https://github.com/jvanasco/pyramid_route_7) that extends the config to allow macros.  Instead of adding a route with `add_route` you use `add_route_7`, which then expands the macro and calls `add_route` behind the scenes.  That technique might help you a bit too.

Andrew McNamara

unread,
Mar 26, 2018, 1:24:14 AM3/26/18
to pylons-discuss
I'm doing something similar now - I've wrapped add_route, and the wrapper expands the {foo} into explicit non-greedy regexs:

def add_dot_route(config, name, pattern, *a, **kw):
    "Permit routes with dots like pylons, eg {entity}{.format}"
    dotnames = re.findall(r'{\.([^}]+)}', pattern)
    if dotnames:
        # Replace {field} with an explicit non-greedy version so {.format} works
        pattern = re.sub(r'\{([_a-zA-Z][_a-zA-Z0-9]*?)\}', r'{\1:(?:[^/]+?)}', pattern)
        pattern = re.sub(r'\{\.([_a-zA-Z][_a-zA-Z0-9]*?)\}', r'{\1:(?:\.[^/.]+)?}', pattern)
    config.add_route(name, pattern, *a, **kw)

I could probably simplify the regex subs (and collapse them into a single re.sub). The result doesn't work quite as well as pylons, though (the view sees the leading dot).
Reply all
Reply to author
Forward
0 new messages