Re: [Zope-dev] Missunderstanding of DTML Methods and acquisition?
This thread is more appropriate for the main list. zope-dev is for development topics. "R. David Murray" wrote:
I'm finding this to be one of the trickiest "simple bits" of dtml to learn, even after having read the docs. The following should work in your /user/regions/index_html (tested):
<dtml-var IManager>
As you may already know, the following will instead get you quoted text of the IManage method:
<dtml-var "IManager">
The following will also work (tested):
<dtml-var "IManager(_.None,_)">
This passes a 'client' of None and the namespace (that img exists in) to the method. (I presume that in the first working example above Zope supplies the client and namespace to the method when it evaluates it).
Correct.
This call form is of course what you'll need if you want to pass arguments to the method:
<dtml-var "IManager(_.None,_,somearg='someval')">
What I'm most confused about right now is when it is necessary to pass the client and namespace and when you can omit it.
It is necessary when you want to call a DTML Method or Document from a Python expression and you want that DTML Method or Document to be able to look things up as an attribute of a 'client' or in your current namespace (or any namespace you provide). You can omit it when you are using a DTML Method or Document _by name_ in DTML. Note that: <dtml-var IManager> is the same as: <dtml-var name="IManager"> and: <dtml-var "IManager()"> is the same as: <dtml-var expr="IManager()"> So most people use the first and third shorthand forms to use an object by name and to execute a python expression respectivly. When the DTML Engine sees that you are using an object by name, it tries to do clever things, like detect if it is a DTML object and to call the method and pass the namespace 'magically'. When the DTML engine sees that you are using an expression, it assumes you know what you are doing and does no magic for you. Therefore, you must explicitly pass in the namespace.
I'm also very unclear as to just what the 'client' is, especially since most of the examples I've seen involve passing in None for the client.
The 'client' is an object that you want to use as a namespace. For example, if DTML Method 'IManager' wants to find the name 'img' you can pass a client object, and the method will try and do a getattr(client, name) (in this case, name being 'img'). If you pass a namespace, then it will try and do a namespace[name]. If neither of these succeed, it will look for the name in the optional list of keyword arguments you can provide. If that fails, it raises a NameError. The reason why it is None in most cases is because you want your method to look things up using the Zope DTML Namespace (affectionately known as '_'). In some special case however, you may want to explicitly provide some other object. This is single handedly the #1 obfusication in Zope and the most frequently asked question. We, of course, did not obfusicate this on purpose. When DTML was first concieved it worked by name only, so the behind the scenes magic was acceptable and intuitive. Later, we added python expressions, and the ugliness of calling DTML Methods and Documents became aparent. -Michel
participants (1)
-
Michel Pelletier