[Zope] Acquisition confusion: more info

Amos Latteier amos@aracnet.com
Mon, 26 Apr 1999 00:03:08 -0700


At 04:00 PM 4/26/99 +1000, Richard Jones wrote:
>In a simplified, contrived system, I have DTML Documents 'foo', 'bar' and 
>'spam'. The entire contents of these files are:
>
>foo  = '<!--#var bar-->'
>bar  = '<!--#var spam-->'
>spam = 'This is Spam!'
>
>This example works as expected. That is, the document foo contains 'This is 
>Spam!'. Changing foo to be '<!--#var "bar()"-->' results in a KeyError on
the 
>name "spam".
>
>I get the same results if I use DTML Methods. What do I have to do to get 
>"bar()" to work?

Firstly, check the Advanced DTML HowTo it has lots of good information.

  http://www.zope.org/Documentation/HowTo/DTML

Now on to your question. If I understand correctly, issue is "How do I call
a DTML Document or Method?" The answer is provided in the DTML User's
Guide. In short, when calling a DTML Document or Method you must provide

  * A client object.
  * A mapping object.
  * Optionally you can provide keyword arguments.

As is also explained in the DTML User's Guide, Zope normally calls DTML
Methods and Documents with the enclosing Folder as the client, and the
REQUEST as the mapping. 

So the reason you get a KeyError when calling bar with no arguments is that
bar has nothing to look 'spam' up in. If you pass the enclosing folder
(available as the first parent of the current document or PARENTS[0]) as
the client argument, then it will use acquisition to find spam. 

  <!--#var "bar(PARENTS[0])"-->

The standard idiom is to pass the client and the REQUEST as the mapping
along with any extra keyword arguments you want.

  <!--#var "bar(PARENTS[0], REQUEST, super='dooper')"-->

This calls bar in a reasonable way and allows you to add extra calling
arguments.

-Amos

P.S. Another interesting way to pass additional arguments to other DTML
Documents and Methods is to use the 'with' tag. For example try this
experiment with your three document setup. Change 'foo' to

  <!--with "_.namespace(spam='my spam')"-->
  <!--#var bar-->
  <!--#/with-->

And see what happens.

P.P.S. Did I mention to check out the Advanced DTML HowTo ;-) There's a lot
of information there.