[Zope3-dev] Context and Component Lookup
Phillip J. Eby
pje@telecommunity.com
Wed, 06 Aug 2003 10:09:39 -0400
At 06:57 AM 8/6/03 -0400, Jim Fulton wrote:
>To implement this simpler component lookup strategy will require
>resorting to a thread-global variable. This thread global variable
>will be set during URL traversal and (probably) cleared when a request
>is closed.
You might be able to do that a lot more simply, if you just use an explicit
context object, and the context object has methods to look up views,
etc. In peak.web, I use a TraversalContext class, mainly to be able to
compute relative and absolute URLs of resources, but you could use a
similar approach for this.
Basically, a TraversalContext holds a reference to the interaction (a
per-request IPublication, but for zope.app you could just hold the request
instead), a traversable (the content object adapted to a traversing
protocol) and a subject (the original content object). A traversal context
also knows its parent context.
By calling a method on a traversal context, passing in a name, you can get
a new traversal context that's a child of the previous context, and has
traversed to the appropriate content object. So, in peak.web, the main
thing that gets passed around are these context objects, because they give
access to everything: the request, traversal adapters, and content
objects. They can safely cache a variety of things, they can delegate
aspects of their behavior to the traversal or content objects, and so
on. And, in peak.web they have the equivalent responsibility of adapting
content objects to viewable entities. See ITraversalContext:
http://cvs.eby-sarna.com/PEAK/src/peak/web/interfaces.py?rev=HEAD&content-type=text/vnd.viewcvs-markup
> In the unlikely event that a thread spawns a new thread,
>the global variable would be carried to the subthread, providing that
>a specialized API is used to spawn the subthread. I don't really like
>using thread globals (or any globals, for that matter), however, I
>think that this is a case where the improvement in simplicity and
>efficiency of component lookup justifies the global variable.
*Shudder*. I think you'd be better off just making the context explicit,
but perhaps I'm biased. I suppose it also might require a lot more
refactoring in zope.app to replace use of implicitly context-wrapped
objects with an explicit context. For peak.web, I only had a few modules
to refactor when I realized this would simplify things.