[Zope] "virtual" subobjects

Amos Latteier amos@aracnet.com
Thu, 05 Aug 1999 23:42:21 -0700


At 12:54 PM 8/6/99 +1000, Tim Potter wrote:
>I'm grappling with the idea of having "virtual folders" (for want of a
>better term) existing under a Zope folder and am not sure how to
>implement it.  The user will basically be navigating through
>subobjects whose identity will be stored in a database:
>
>http://somehost/notes/a/b/c
>
>where a, b, c correspond to some structure in the database.  My
>question is it possible for the object at http://somehost/notes to
>handle all requests to subobjects under it without creating them by
>hand in Zope?  I suspect some Python programming would be involved but
>I'm not sure what.

I'm pretty sure this is documented somewhere, I'm just not sure where, so
here goes.

The Zope ORB will publish sub-objects by using getattr and getitem by
default, but you can control its traversal process manually with the
__bobo_traverse__ hook.

If an object defines a __bobo_traverse__ method, then that is called to
traverse the object. __bobo_traverse__ is called with two arguments, the
REQUEST and the entry name or URL fragment. The method should return a
subobject named by the entry name or None. You can also return a tuple of
objects indicating that they are all traversed (this is a way to sneak
extra objects in the PARENTS list).

So in your example you want to write an object that will gobble up all the
entry names that follow it. Here's how that could be done,

    def __bobo_traverse__(self, REQUEST, name):
        "I am my own sub-object"
        return self

I think I learned this trick from Phillip Eby, but I can't remember ;-)

Later you can consult the REQUEST to determine what the path info was.

Actually, now that I think of it you'll need something a little more
complex, since you need to actually publish something in the end.
ZPublisher will try for the 'index_html' method, but that's just more of
the same, so you can either explicitly do some testing in __bobo_traverse__
to return 'index_html' when asked, or you can rely on __call__.

Here's a minimally working example,

  class PathEater:
      "Eats path info for breakfast"
    
      def __init__(self):
          self.steps=[]
    
      def __bobo_traverse__(self, request, name):
          self.steps.append(name)
          return self
          
      def __call__(self):
          "Publish method"
          return "I ate %s" % self.steps

If you want to experiment with stuff like this I highly recommend using
ZPublisher.Test and ignoring the Zope framework until you understand object
publishing on a more basic Pythonic level.

Good luck!

-Amos