Let's say I have a route '/foo/bar/baz'. I would also like to have another view corresponding to '/foo' or '/foo/'. But I don't want to systematically append trailing slashes for other routes, only for /foo and a few others (/buz but not /biz)
From what I saw I cannot simply define two routes with the same route_name. I currently do this:
config.add_route('foo', '/foo')
config.add_route('foo_slash', '/foo/')
config.add_view(lambda _,__: HTTPFound('/foo'), route_name='foo_slash')
Is there something more elegant in Pyramid to do this ?
Found this solution when I was looking for the same thing for my project
And then during route configuration,
Rather than doing
config.add_route('events','/events')
Basically it is a hybrid of your methods. A new route with name ending in
_auto
is defined and its view redirects to the original route.EDIT
The solution does not take into account dynamic URL components and GET parameters. For a URL like
/abc/{def}?m=aasa
, usingadd_auto_route()
will throw a key error because theredirector
function does not take into accountrequest.matchdict
. The below code does that. To access GET parameters it also uses_query=request.GET
Pyramid has a way for
HTTPNotFound
views to automatically append a slash and test the routes again for a match (the way Django'sAPPEND_SLASH=True
works). Take a look at:http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html#redirecting-to-slash-appended-routes
As per this example, you can use
config.add_notfound_view(notfound, append_slash=True)
, wherenotfound
is a function that defines yourHTTPNotFound
view. If a view is not found (because it didn't match due to a missing slash), theHTTPNotFound
view will append a slash and try again. The example shown in the link above is pretty informative, but let me know if you have any additional questions.Also, heed the warning that this should not be used with POST requests.
There are also many ways to skin a cat in Pyramid, so you can play around and achieve this in different ways too, but you have the concept now.
I found another solution. It looks like we can chain two @view_config. So this solution is possible:
Its behavior is also different from the question. The solution from the question performs a redirect, so the url changes in the browser. In the second form both /foo and /foo/ can appear in the browser, depending on what the user entered. I don't really mind, but repeating the renderer path is also awkward.