[ZDP] changing contexts in zope - part 2 - draft 1

Rik Hoekstra hoekstra@fsw.LeidenUniv.nl
Mon, 15 Nov 1999 09:52:37 +0100


Hello everyone,

I prepared a sequel to my part 1 of the changing context chapter posted last
week.
Please sent me your comments and reactions, if only to keep up my motivation
to go on.

This draft ends with an incomplete plans section, which I shall repeat here.
To this part I _also_ would like your reactions, as they (also) touch upon
the dtml rant thread of last week. Particularly: should this also evolve
into a 'best practices' section - if you want to do more intricate things,
change to ZClasses, External Methods, try Python Methods or build a Product.
Should I treat all the esoteric  and convoluted dmtl without further
'advice' (as if anyone would take that).
Since this is going to be a ZBook, these seem to be relevant questions to
answer here and now.


[Plans:

this section goes on with the problems encountered in acquisition, when you
have
folders at the same level, but treat them as if they were hierarchally.

If someone has additions or other misconceptions, please let me know.

The next chapter will be about

Conditional and dynamic properties

treating such items as:
- checking for properties/items
- indirectly referencing variables/properties/methods (blegh - I don't
even know if I know this myself -oh well)
- inserting new objects programmatically through dtml

(and all issues addressing namespaces as needed - perhaps I should
elaborate here on using python for this - suggestions anyone???)]


Rik

=============================================
changing contexts in zope - part 2 - draft 1
==============================================
3. A closer look at acquisition

There is much more to be said about acquisition, and so there is in a
separate
chapter, so we do not pretend to give an exhaustive treatment here.
Nonetheless, acquisition is crucial to changing contexts in Zope, so
we shall go into some more examples here. A few simple examples to begin
with - we shall relate it to more general design questions.

3.1 Example 1

One of the elements in the pages we described above was a
hierarchy_links, displaying the links of the pages all the way up to the
root.

The DTML Method hierarchy_links was listed as follows [*if you are not
at all familiar with DTML, it is probably necessary to study at least
_some_ of the basics at first. See [link]]

1   <dtml-in PARENTS reverse>
2      <dtml-if sequence-start>
3         <a href="<dtml-var absolute_url>"><dtml-var id></a>
4      <dtml-else>
5         | <a href="<dtml-var absolute_url>"><dtml-var id></a>
6      </dtml-if>
7    </dtml-in>


Analysis:
Line 1:	loop the PARENTS list in reverse order. [* For each object called,
acquisition builds a stack of objects that are higher in the hierarchy
(a namespace stack). These are the parents of the current object, for n
parenst the list is n items long, ranging from 0 to n. See acquisition
chapter]
line 2-3: if it is the first item in the loop, show a link to the item,
else
line 4-5: show a link with a separator.

Now, this shows some of Zope's strength: is a very simple program, but
it works everywhere in your site and follows the changing contexts
without needing to be changed itself.

3.2 Example 2:
It is a in line with the changing colors example we started out with.
Suppose we have a folder called documents, with a document called
boring.html in it. The boring document has content that may be usable in
many places (like address information of your firm). Acquisition makes
it available as

     http://acquisition.com/documents/boring.html

But it can also be available as

     http://acquisition.com/themes/christmas/documents/boring.html

In /themes/christmas you find a new standard_html_header which puts a
gaudy red and green theme on the text, and contains an /images folder with
christmas-oriented versions of the page decorations.  There might also be
a /themes/escher (in which case the url would be
http://acquisition.com/themes/escher/documents/boring.html).

Discussion:
The downside of acquisition is that URL's are not always in the same,
consistent place on your side: acquisition makes hierarchy less absolute.
For example, you have a link to a page called AddressInformation
from both your site's homepage and from a page called Documentation (and
from who knows what other pages).

Without changing contexts, this will result in the same
AddressInformation page having many different urls. This is not exactly
consistent. Even more than in conventional site design, acquisition
makes it possible to design you navigation in a sloppy way ('no need to
move that folder - acquisition will take care of it anyway').

Granted, the different links to a page are no disaster. Still, when you
have a chain of links, url's may become innecessary long, to the
point that they have an adverse effect on Zope's performance. For
example if you have a hierarchy like this

root
  documents
    AddressInformation
    GeneralInformation
  products
    ProductInformation

it is very well conceivable that you end up with a url like this:


http://acquisition.com/products/ProductInformation/documents/
       GeneralInformation/products/ProductInformation/AddressInformation

(this URL did not fit on one line)

[Today I read something about this having been patched in Zope 2.1 - is
that right? If so, this section must be thrown out]

By the way, Zope _does_ give you a way to address this issue, by linking
not through a relative link (<a href="desired_page">), but by linking
absolutely (<a href="<dtml-var "desired_page.absolute_url">).

3.3 Common misconceptions about acquisition

The very dynamics of acquisition in Zope can easily confuse you.
Moreover, once you start pushing acquisition to its limits, it is
important to know how it works and how it does not.

Many people who start working with Zope have a misconception about
acquisition. Technically put, acquisition builds a namespace stack
from the root to the object called. In looking through the stacks it
first looks for the required object in the current namespace, then goes
up one step in the namespace stack and goes looking in that object and
its context.

Next is an illustration of one of the misconceptions about
acquisition is from an actual question to the Zope list. Incidentally,
the Zope list, its sister lists (at the time of writing Zope-dev and
ZDP), and their archives are a great resource for examples [URL] and
explanations about Zope.


Question:

Take I the following folder structure:

 /
    index_html
    show_images
    /images
        bob  <image object>
        henry <image object>
    /subfolderhenry
        index_html
        /images
            henry  <image object>

The /index_html uses show_images to display /images/bob and /images/henry

I want my /subfolderhenry/index_html to use show_images to show
/images/bob and /subfolderhenry/images/henry.

When /subfolderhenry/index_html is rendered, the acquisition method goes
looking for <dtml-var images/bob>.  What seems to be happening is that
it looks in /subfolderhenry/images and doesn't find bob.  The problem is
that it returns an error instead of moving up the tree to look in
/images (where it would find bob).

The person in question wanted to know why this did not work: whether he
mis-understood the way acquisition works, or whether this was a bug or
Zope problem.

Exercise: Can you figure out the answer for yourself?

Analysis

There was a misunderstanding of acquisition, of course.
In the hierarchy presented, if Zope is asked for
subfolderhenry/images/henry, it goes looking for an images folder in
subfolderhenry and finds one. It does not find the image (object) henry,
because it's not there. However, as it already found an object called
images, it does _not_ go on, but stops and reports a not found error.

The misconceptions about acquisitio, is the way that Zope goes looking
for an object. Some starters with Zope is able to 'step back' when it
does acquisition. For example, in the question above the suppose Zope to
go looking inside an object looking for a folder object called images.
If it has one, it goes looking for an actual image object (the object
called - in this case henry). If it does not find one, Zope steps back,
and once more resumes its climb up the acquisition hierarchy to go
looking for other images objects.

That is _not_ the case, and for many good reasons. If it did (even if it
were technically conceivable), it would produce inpredictable results and
make acquisition even more complicated than it is now.


Solution

Now that the question is answered, it still needs a proper solution. The
author of the question wrote: as a work-around I can drop the images
directories, and host the images in the actual directories.  Not a great
solution though - I agree

Another exercise: find a solution.

In the post and its answer the following alternatives were presented:

A. Ask yourself if you really need an images folder in each folder, or
whether you could do with one images folder somewhere high in the
hierarchy. Then a reference to images from below that point is always be
to the same images folder.

B. you can refer to the images folder in the root explicitly:

<dtml-var "PARENTS[-1].images.henry"> (note: PARENTS[-1] always is the root
folder)

Of course, this is equivalent to the normal HTML

<IMG SRC="/images/henry">

but then you would have to specify the image attributes by hand, where
in the first case you can have Zope represent them, as follows:

<dtml-var "PARENTS[-1].images.henry,tag(border=0, align='right')">

C. you could name you root images folder 'images' and the images
folder in the henry folder 'Images', as Zope is case sensitive, it
will distinguish them from each other. The only problem is that _you_
are likely to mix them up.


[Plans:

this section goes on with the problems encountered in acquisition, when you
have
folders at the same level, but treat them as if they were hierarchally.

If someone has additions or other misconceptions, please let me know.

The next chapter will be about

Conditional and dynamic properties

treating such items as:
- checking for properties/items
- indirectly referencing variables/properties/methods (blegh - I don't
even know if I know this myself -oh well)
- inserting new objects programmatically through dtml

(and all issues addressing namespaces as needed - perhaps I should
elaborate here on using python for this - suggestions anyone???)

----------------