Sunday 21 October 2007

Cookin' with traverse_subpath


I've heard a few people mention this, so I thought I'd post this recipe. We're using a simpler version in Vice to prettify some URLs, but it was so easily generalised I knocked an example together.

The idea is that the traverse_subpath variable from Script (Python) was a nice recipe for getting information from URLs. You might have a URL http://127.0.0.1:8080/test/traverse_subpath/a/v/121/a/a/a/1213 and want the list ["a", "v" "121", "a", "a", "a", "1213"].

It turns out that as z3 views are based on their own traversal mechanism, it's really easy to override to get something to emulate this behaviour.

So, set up your view as you usually would, but note the subtle differences from the boilerplate:

traversesubpath.py
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.publisher.browser import BrowserPage

class subpath(BrowserPage):

def __init__(self, context, request):
self.context = context # Use Martin's aq_magic
self.request = request
self._path = []

def publishTraverse(self, request, name):
self._path.append(name)
return self

@property
def traverse_subpath(self):
return self._path

__call__ = ViewPageTemplateFile('traversesubpath.pt')


traversesubpath.pt
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
lang="en"
i18n:domain="plone">

<ul>
<li
tal:repeat="pathitem view/traverse_subpath"
tal:content="pathitem" />
</ul>

</html>
With the URL I gave above, I get the following page rendered:
  • a
  • v
  • 121
  • a
  • a
  • a
  • 1213

It's that simple.