Hey all, these never got to the list, but the solution at the bottom might be of interest to others...

On Oct 3, 2005, at 10:19 PM, Duncan M. McGreggor wrote:

I would like the alias to occur further back in the object hierarchy:


So, to summarize:
1) is this type of traversal modification possible in z3?, and
2) how would one go about doing this?

I've continued to dig on this one, and the only thing I can come up with is a brute-force attempt. My thoughts are these:

1) If I can override the publisher (zope.app.publication.zopepublication?), 2) I could use request.getTraversalStack() and do manual checks on the path, and
3) For anything meeting my requirements, I do additional processing
4) For everything else, pass it back to zope.app.publication.zopepublication

Is this sane?

If so, how would I go about "overriding the publisher"?

If this is not sane, what is?

Okay, I keep self-replying... sorry! I'm reading more code and trying to think these things through...

In zope.app.publication.publicationtraverse, the PublicationTraverse method traverseName() does the following check:

    if IPublishTraverse.providedBy(ob):
        ob2 = ob.publishTraverse(request, nm)

This happens before the check that does this:

    raise NotFound(ob, name, request)

The NotFound has been my biggest concern, since I don't think I can use the standard Traversal behavior-changing tricks. Meaning a suitable container for the content would never be arrived at, and so I'd get a NotFound error. However, if I can do something with the check I mentioned above, it'd be before the NotFound was generated... so if whatever the "ob" object is implements IPublishTraverse, I should be home-free, right? Meaning I should be able to do all the "virtual directory" processing in ob.publishTraverse(). The trick is, if it's not actually getting to an object nor a real container, what *is* ob? Hmm... this is eerily familiar ;-) Sounds like a chapter in the z3 book ;-)

From zope.app.traversing.interfaces.ITraversalAPI's docstring:

  Traverse a single step 'name' relative to the given object.

'name' must be a string. '.' and '..' are treated specially, as well as
  names starting with '@' or '+'. Otherwise 'name' will be treated as a
  single path segment.

  You can explicitly pass in an ITraversable as the
  'traversable' argument. If you do not, the given object will
  be adapted to ITraversable.

  'request' is passed in when traversing from presentation code. This
  allows paths like @@foo to work.

  Raises TraversalError if path cannot be found and 'default' was
  not provided.

This is interesting. Beyond that -- this is most excellent documentation. It clarifies some misconceptions I've had about traversal. From this, I gather that I *should* be able to use the tricks that are published in Stephan Richter's book and in the schooltool code. I just have to do it further towards the root of the object hierarchy. It seems that I will have to create a "site" container (implementing IFolder), since it is that point in the traversal process (at the level of the site) that I need to override publishTraverse().

This has been really, really long winded... I wanted to expose as much of my thought process as possible to both get the best assistance as well as provide something for future readers.

For the experts out there, is my assessment correct?

To answer myself: yes, it is correct. I took a break, watched a movie, came back and wrote the code that only varied from Stephan's book example in the most minimal ways. I then restarted zope, added a new Site (which implements my ISite, that the custom traverser operates on), dumped all the content and the ++etc++site/default into the new one with the custom traverser, and bingo! it worked. Not even a hiccough.

Here's an example of the real location of an object in the site:


And now, with the traverser, all of the following resolve and present the same object as above:


I am frothing-at-the-mouth deliriously happy with z3. And its designers. Not so much about this little victory (though it is sweet), but rather because of the source of this little victory: the design and beauty of z3 itself.

At the PyCon2004 sprints, I worked with Chris McDonough and others on replacing the Zope 2 web server with a twisted version. For part of that, I spent some time hurting my eyeballs and brains trying to grok the Zope 2 request lifecycle and the publisher source code. It really, really hurt and I didn't understand much. I have resisted looking at z3's deep internals in part due to that past pain and the fear that I would meet similar dragons of my own ignorance. Not so. The component architecture of z3 is so simple, consistent (as far as I can tell), pervasive, and (honestly) fundamentally beautiful, that with a well-expressed docstring, understanding is almost effortless. I will be reading the internals of z3 from now on, with no fear :-)

Jim, Stephan, and the rest of the community: you guys have done an amazing, unbelievable job. Thank you for this gift to the software world :-) It's really changing the way I think about development, my development process, and ultimately, the quality and functionality of what I develop.


Zope3-users mailing list

Reply via email to