When URL Dispatch is used, we can easily generate a URL to a view because every view has a distinct route_name like:
login.py:
@view_config(route_name='login')
index.pt:
<a href="${request.route_url('login')}">Login</a>
But how to do this in traversal? Since there is no instance of resources 'Login' available, I don't know how to generate URL to view login.
In traversal you are required to know the structure of your tree, and you must be able to load context objects on demand. The URLs are generated with respect to a context, using its location-aware properties __name__
and __parent__
to build the URL.
/
|- login
|- users
|- 1
|- edit
So let's say we have a User(id=1)
context object, and we want to login. If your view is registered via @view_config(context=Root, name='login')
, then you can generate the url via request.resource_url(request.root, 'login')
. This is us telling Pyramid to generate a URL relative to the root of the tree.
On the other hand, if we are at login and we want to take the user to edit you must load a location-aware User
object for that user in order to generate the URL. request.resource_url(user, 'edit')
where user
is an instance of User(id=1)
with valid __name__
and __parent__
attributes.
If you pass in a context without a location-aware __parent__
the URL will be generated as if your user was mounted at /
because that's the only sane place for Pyramid to think the object would be in your tree.
The ability to load a location-aware object is why we stress that traversal works best with a persistent tree of objects, not one that is generated on the fly. It's much more convenient to directly load the user and have its __parent__
and __name__
already populated for you if you want to generate URLs for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With