Phillip, Thank you for your email - very helpful! Before getting your email, I also started snarfing the PythonScript.py code into something I could whittle down to the minimal code needed. However, it looks like you have beat me to it, but your solution leaves with with a few questions: 1) Are you saying that it is unnecessary for my Product's class to inherit from the Script class? Are there any special classes that it should it inherit from? 2) I found __before_publishing_traverse__ in the Bindings .py, do I just put this method in my poduct's class? PS: I might note that zope-2.7.2's method looks a little different... 3) I understand having an index_html method, but how did __before_publishing_traverse__ method get executed before its called? Thanks! Kent Phillip Hutchings wrote:
Actually, it appears to be. I had the same problem with my as-yet incomplete blog that I wanted to have URLS much as you describe. I figured it out though. traverse_subpath is only set for ZPT, DTML and Script (Python) objects, as far as I can see, so I snarfed the code from the python script class. You need this code for it:
This will allow Zope to traverse down as far as it likes and add it to a variable in request called 'traverse_subpath'
def __before_publishing_traverse__(self, self2, request): path = request['TraversalRequestNameStack'] if path and hasattr(self.aq_base, path[-1]): return subpath = path[:] path[:] = [] subpath.reverse() request.set('traverse_subpath', subpath)
and then in your index_html method you need to decode the subpath and then do what you want with it, here's what I do at the moment: def index_html(self, REQUEST=None, *args, **kw): """Serve up blog requests""" traverse_subpath = REQUEST['traverse_subpath'] if len(traverse_subpath) == 0: # We return the index page return self.blog_index_html(self, REQUEST, **kw) elif len(traverse_subpath) == 1: item = traverse_subpath[0] if re.match(r"[1-2][0-9]{3}", item) is not None: return "Year match %s" % item else: return "Other match %s" % item else: return "Deep nesting, item is %s" % '/'.join(traverse_subpath)
Hope this helps a bit. The individual path elements are stored as an array, starting from the left most element after the last 'real' object, ie the instance of this class.