IPublishTraverse and subpath

Hi,
today I have a problem with IPublishTraverse

How can I send requests to my BrowserView (which implements IPublishTraverse) with multiple subpaths?

This one works: --> @@filter/123

view = getMultiAdapter((nav_root, self.request), name=u'filter')
filtered = view.publishTraverse(self.request, '123')

But how can I archieve this --> @@filter/123/123/123/... and so on (depend on selected filters)
this one does not work:

view = getMultiAdapter((nav_root, self.request), name=u'filter')
filtered = view.publishTraverse(self.request, '123/321/421/12')

Or is there a better solution, I don't want to use GET-Parameters (eg. varnish...)

thanks :slight_smile:

The publishTraverse is responsible to handle one step (usually identified by the material between two consecutive /s) in the traversal process; the result is an object that can then handle the next step, either directly or via another publishTraverse view.

There are ways to handle multiple steps together by modifying the internal Request data controlling the traversal. However, the approach is not easy. To use it, you must understand what happens in ZPublisher.BaseRequest.BaseRequest.traverse (this is the traversal implementation). In short: request['TraversalRequestNameStack'] contains the steps still to do, in reverse order. In order to generate correct url information in the request, it may be necessary to update request.steps or request._steps.

Thank you, TraversalRequestNameStack was a good hint, I'll try it tomorrow ...

This is my pattern for subpaths with browser views:

@implementer(IPublishTraverse)
class VersionedDocument(BrowserView):

    def __init__(self, context, request):
        super(VersionedDocument, self).__init__(context, request)
        self.subpath = []

    def publishTraverse(self, request, name):
        if not hasattr(self, 'subpath'):
            self.subpath = []
        self.subpath.append(name)
        return self

    def external(self):
        fn = u'/'.join(self.subpath)

In this case you can get hold of the subpath in the view external through the concatenation of the self.subpath list.

-aj

1 Like