Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate URL to view when using Traversal?

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.

like image 440
Lingfeng Xiong Avatar asked Dec 26 '22 08:12

Lingfeng Xiong


1 Answers

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.

like image 169
Michael Merickel Avatar answered Dec 28 '22 22:12

Michael Merickel