[Zope3-Users] Specialized URL traversal.. Best way?

Jeff Shell eucci.group at gmail.com
Fri Dec 30 01:22:28 EST 2005


This week I've been revisiting some of my early Zope 3 ideas in a
small new application we plan to use internally. One of the core
concepts of this system is 'tagging', similar to del.icio.us, flickr,
snippets, etc. Old versions that I wrote managed tags manually, with a
'taglib' object and tags being their own indexes that manually tracked
the documents that mentioned them. I wanted to use the catalog, but
the required indexes weren't available or usable by me at the time,
and then other projects came along.

In the last version I wrote prior to now, I wrote a custom Traversable
adapter for this 'taglib', which was BTreeContainer.

zope.app.traversing.interfaces.ITraversable - traverse(name, furtherPath)

I used 'furtherPath' to go along and turn paths like
'zope/enterprise/cms' into tags to search (again, using a manual
system due to lack of catalog). Since this was on a custom container,
it somehow worked.

So today, I thought I could provide a similar adapter, but on a view
object, that could get the rest of the requested path in one swoop
that I could then use to query a SetIndex in the catalog. But no
matter what I did, I couldn't get it to work. It doesn't seem like my
ITraversable gets called at all for my view - even with that view
providing the interface I say I adapt and on and on. I could get my
traversable adapter from the interpreter, but it wasn't ever touched
during the zope.publisher publication process. At best, I figured that
'publishTraverse()' was where I needed to go based on the errors that
I kept having. But publishTraverse() deals with one name at a time...
But it does pass in the request. And at most, I guessed that the
traversal stack was what I needed. Again, this is to have URLs like:

myapp/@@tags/zope/viewlet

And turn that into a catalog search for anyof {'zope', 'viewlet'}

    def publishTraverse(self, request, name):
        namestack = request.getTraversalStack()
        if name not in namestack:
            namestack.append(name)
        namestack.reverse()
        tags = tuple(namestack)
        request.setTraversalStack([])

        results = TaggedArticleFinder(self.__name__,self.__parent__,tags)
        results.prepareSearch(request)
        return results

The 'TaggedArticleFinder' then provides an interface that a view can
be found for that displays the results. So I've got it all working
now... But it seems kindof awkward. There are a few different
traversing options, and knowing which one applies when is difficult to
figure out. And monkeying with the traversal stack.. Is that really
what I should be doing here? It seems like the interface for
ITraversable that specified 'furtherPath' is what I'd like to be using
when I'm wanting to play with the whole path from this point on.

I ultimately want to provide a few more options similar to this one
for things like date based filtering (urls like @@bydate/2005/12 or
2005/12/29). None of these are containers or real objects, just URL
segments used to construct a query.

I was wondering - is this the best way to do this? Is there a better
recipe floating around out there? I appreciate Zope's direct-to-object
URL publishing (been using it since '97!), but custom URL maps past a
certain object like a view seem to be quite tricky, whereas Django and
generic toolkits like Routes are specializing in ways of managing
custom URL maps. I know there are a few places where one can take over
this process, but it's not obvious when and how to use them, or which
to use. BeforeTraversal event? publishTraverse? ITraversable?
ITraversing? Ultimately I'd like to put a couple of views into the
root of my app that can do something akin to Django's url_dispatch:

http://www.djangoproject.com/documentation/url_dispatch/

where a set of patterns and a name are used to allow for various
dynamic queries. The name would be used to look up a component to
respond to the matched items in the path. It wouldn't interfere with
any other traversal (ie - wouldn't replace the default way of doing
it). Doing it from a browser view seems safest, since this is almost
exclusively about keeping nice URLs for web browsing. I just want to
know the best place to plug in.


More information about the Zope3-users mailing list