[Zope] Acquisition and/or Traversal ?
Dylan Reinhardt
zope@dylanreinhardt.com
Tue, 28 Jan 2003 14:34:43 -0800
At 01:14 PM 1/28/2003, D2 wrote:
>Needing a starting point to understand how traversal and acquisition work
As a starting point, about 90% of what you need to know about acquisition
can be summarized thus:
1. Acquisition works by containment or context.
2. Containment trumps (precedes) context.
To put this less formally, the relationship defined between two objects in
the ZMI is more tightly bound than the relationship suggested by the
construction of a URL. This should make a lot of sense, hopefully.
Traversal is mostly a fancy way of building an acquisition context or
specifying a particular object to render. Since containment trumps
context, it follows that traversal should be thought of as a less optimal
way to use acquisition.
I would suggest that containment-oriented design (not traversal) should be
your default choice for an acquisition strategy. There are cases that call
for acquisition by context and heavy traversal, but containment is easier
to design for and more generally useful. In most projects I've done, the
need to perform significant traversal indicates that some refactoring may
be in order.
>In this example company, a subsidiary must establish proposal based on a
>product list. If it doesn't have products, it must use the headquarter's ones.
>
>1 with this hierarchy, how can i reach the Product list in the Products
>Folder from Proposal 1 of Subsidiary 1 ?
Since it sounds like the purpose of your hierarchy is to drill down from
general to specific, not to partition different levels of security, what
about the following:
/
+---Products/
- item1
- item2
- item3
+---Sub1/
- item1
- item3
+---Proposals/
+---Etc/
The URL: /Products/Sub1/item1
will find the item1 object in the Sub1 folder.
The URL: /Products/Sub1/item2
will find the item2 object in the folder just above Sub1.
The name item2 can't be resolved by Sub1, but *can* be resolved by Sub1's
container. Ta da! It works and you're done. Not bad, eh?
This pattern is easy enough to nest if you should need more than two
layers, BTW.
>2 If Products weren't folder but objects and items weren't contained
>objects but properties of Products, would the solution be the same ?
Probably not, the way you have it, unless you specifically designed the
objects to work that way.
If an object can't resolve a name, it will look in its container object, in
its container's container, etc., and then back up the chain defined by
context. It won't be looking for an object named Products (necessarily)
that can resolve the method item1, but for *any* object in the acquisition
chain that can resolve "item1". You would probably need to give each
different Products object a different name so that you could define a
"fall-through" acquisition relationship, thus:
/hq_products/sub1_products/item_property
In this example, hq_products is the same type of object as sub1_products...
they just have different methods/attributes available.
When item_property *isn't* resolved by sub1_products, you've ensured that
there is an object further up in the acquisition chain which *can* resolve
the name (assuming the name can be resolved at all). I'm assuming that
hq_products is contained by something found in the containment hierarchy of
sub1_products. I'm pretty sure you'll have a difficult time pulling this
off if you don't give the different Product objects different names... and
that's a requirement that may impose significant limitations.
If you're locked into the hierarchy you've defined, you'll probably need to
create some kind of "observer" or "viewer" method that traverses your
hierarchy in specifically designated ways under specific conditions. This
is easy enough to do, but I would suggest that designing your hierarchy to
suit your acquisition requirements might be the simpler, faster, and more
durable solution.
$.02... HTH
Dylan