Hi everyone, I'm trying to figure out how to do something here while avoiding nested dtml tags. Here's what I've got: I have a TinyTable containing two fields: "name" and "status". I have a DTML Document in the same folder as the TinyTable for each "name" in the TinyTable. I want to display that DTML Document based on the value of "status" in the TinyTable. Here's some code: <dtml-in testTable> <dtml-if "status <> ''"> <p><<< insert DTML Document here >>></p> </dtml-if> </dtml-in> So in the code above I want to insert <dtml-var spam_html> (which is a DTML Document in the current folder), for example, if the TinyTable contains a line that looks like: "spam_html", "X" I hope I'm making myself clear. Anyone have any ideas? -Tim -- Tim Wilson | Visit Sibley online: | Check out: Henry Sibley HS | http://www.isd197.k12.mn.us/ | http://www.zope.org/ W. St. Paul, MN | | http://slashdot.org/ wilson@visi.com | <dtml-var pithy_quote> | http://linux.com/
Timothy Wilson wrote:
Hi everyone,
I'm trying to figure out how to do something here while avoiding nested dtml tags. Here's what I've got:
I have a TinyTable containing two fields: "name" and "status". I have a DTML Document in the same folder as the TinyTable for each "name" in the TinyTable. I want to display that DTML Document based on the value of "status" in the TinyTable.
Here's some code: <dtml-in testTable> <dtml-if "status <> ''"> <p><<< insert DTML Document here >>></p> </dtml-if> </dtml-in>
So in the code above I want to insert <dtml-var spam_html> (which is a DTML Document in the current folder), for example, if the TinyTable contains a line that looks like:
"spam_html", "X"
I hope I'm making myself clear. Anyone have any ideas?
-Tim
Possibly this (untested): <dtml-in testTable> <dtml-if status> <p><dtml-var expr="_[status]"></p> </dtml-if> </dtml-in> I don't see any way to safely avoid nesting the dtml-if tag, if status might be empty. This is not anything I would consider a problem though. -- | Casey Duncan | Kaivo, Inc. | cduncan@kaivo.com `------------------>
On Mon, 19 Mar 2001, Casey Duncan wrote:
Possibly this (untested):
<dtml-in testTable> <dtml-if status> <p><dtml-var expr="_[status]"></p> </dtml-if> </dtml-in>
I don't see any way to safely avoid nesting the dtml-if tag, if status might be empty. This is not anything I would consider a problem though.
Cool. That worked. I need to read up on that _[] stuff. Thanks. -Tim -- Tim Wilson | Visit Sibley online: | Check out: Henry Sibley HS | http://www.isd197.k12.mn.us/ | http://www.zope.org/ W. St. Paul, MN | | http://slashdot.org/ wilson@visi.com | <dtml-var pithy_quote> | http://linux.com/
Timothy Wilson wrote:
Cool. That worked. I need to read up on that _[] stuff. Thanks.
Knowing Python really helps in decrypting _['x']. First of all, _ is just a valid, albeit weird, variable name in Python. _ does not have any special powers in Python (as $_ has in Perl). The syntax y['x'] means: fetch item 'x' from dictionary y. y is not a real dictionary, but rather an object that behaves mostly like a dicionary. So _['x'] just means, fetch item 'x' from the namespace. In a dicionary, whatever goes inside the [] is called a "key". Now, what happens if I write y[x] and not y['x']? That is an indirection, is is discussed a few paragraphs below. Now, although _ would be just a regular variable name in Python, in DTML expressions it always refers to the namespace object which, like I said, is not really an object but just pretends to be one. The symbol for the namespace object could be 'namespace', 'super_dict', or '_ground'. But it was called '_'. Zopistas I've met pronounce _ as "under" or "namespace", depending on how formal they are. Like a dicionary, _ has a has_key method, which you call like this: "_.has_key('x')". Unlike a regular dictionary, it gives you access to dozens of Python functions such as int "_.int(x)", and whole modules such as string, DateTime and random: "_.random.randint(x,y)". On the other hand, _ does not have some usual dicionary methods, like keys() or items(), which are useful to retrieve the entire contents of a dictionary. WHAT _['x'] REALLY DOES The strangest thing about _ is that when you access something in it, like _['x'], it doesn't just fetch the x object for you. Whenever _ retrives an object, it checks whether the object is callable (most things are callable objects in Zope). If the object is callable, _ calls or invokes it, which means the object is executed as code, and then what you get is not the object, but the result of executing it, whis is normally a string containing HTML. This is the same behaviour of the dtml-var "name" attribute. So: (1) <dtml-var name="x"> gives the same result as (2) <dtml-var expr="_['x']"> but is not the same as (3) <dtml-var expr="x">. For instance, if x is a DTML Method, (1) and (2) execute, or render it, replacing DTML tags within x by their results, and returning plain HTML. Then if you want to access some z attribute of x, you get the dreadful "String object has no attribute z", which tells you that x is no longer a rich object like a folder or a document, but is now a flat string containing the HTML resulting from rendering the x object. With syntax (3) you just fetch it, which depending on context would display the unrendered DTML code. If you need to indirectly fetch an object without executing it, you have to use another of _'s methods, getitem. The expression "_.getitem('x')" returns a reference to the object called x, without invoking it. INDIRECTION Notice difference between: (2) <dtml-var expr="_['x']"> (4) <dtml-var expr="_[x]"> These mean COMPLETELY DIFFERENT things. In (2) you want to get the object called 'x' from the namespace dictionary. The key you are using is the string 'x'. In (4), you are getting the object whose name is stored in variable x. The key, in this case, is whatever is referred by the variable x. If x refers to the string 'ni', then _[x] means _['ni'], that is, fetch the object called 'ni'. That is why _[x] is called an indirection: in our example you are not fetching 'ni' directly, but indirectly through the x variable. The next time _[x] is evaluated, x may refer to 'sikander', and then _[x] may yield a totally different result. The same rationale goes for (5) <dtml-var expr="_.getitem('x')"> (6) <dtml-var expr="_.getitem(x)"> The result of (5) is the same as (3) <dtml-var expr="x"> so you would never use (5) in real code. But (6) is useful to fetch an object indirectly without executing it. AN INTERESTING EXPERIMENT Try this: within a folder, create two methods with ids 'method1' and 'method2'. Leave 'method2' with its default content, but replace the content of 'method1' with this, then View it. <dtml-var standard_html_header> <dtml-var name="method2"> <hr> <dtml-var expr="method2"> <hr> <dtml-var expr="_['method2']"> <hr> <dtml-var expr="_.getitem('method2')"> <dtml-var standard_html_footer> If my explanations were any good, you should understand what is going on now. The whole _ issue is why, whenever I teach Zope, I include at least one hour of "instrumental Python". And while playing with the Python interpreter, I always make the students create and do lots of operations with a dictionary called _. -- Best regards, Luciano
Luciano Ramalho wrote:
Timothy Wilson wrote:
Cool. That worked. I need to read up on that _[] stuff. Thanks.
Knowing Python really helps in decrypting _['x'].
First of all, _ is just a valid, albeit weird, variable name in Python. _ does not have any special powers in Python (as $_ has in Perl).
The syntax y['x'] means: fetch item 'x' from dictionary y. y is not a real dictionary, but rather an object that behaves mostly like a dicionary. So _['x'] just means, fetch item 'x' from the namespace. In a dicionary, whatever goes inside the [] is called a "key". Now, what happens if I write y[x] and not y['x']? That is an indirection, is is discussed a few paragraphs below.
Now, although _ would be just a regular variable name in Python, in DTML expressions it always refers to the namespace object which, like I said, is not really an object but just pretends to be one. The symbol for the namespace object could be 'namespace', 'super_dict', or '_ground'. But it was called '_'. Zopistas I've met pronounce _ as "under" or "namespace", depending on how formal they are.
Like a dicionary, _ has a has_key method, which you call like this: "_.has_key('x')". Unlike a regular dictionary, it gives you access to dozens of Python functions such as int "_.int(x)", and whole modules such as string, DateTime and random: "_.random.randint(x,y)". On the other hand, _ does not have some usual dicionary methods, like keys() or items(), which are useful to retrieve the entire contents of a dictionary.
WHAT _['x'] REALLY DOES
The strangest thing about _ is that when you access something in it, like _['x'], it doesn't just fetch the x object for you. Whenever _ retrives an object, it checks whether the object is callable (most things are callable objects in Zope). If the object is callable, _ calls or invokes it, which means the object is executed as code, and then what you get is not the object, but the result of executing it, whis is normally a string containing HTML. This is the same behaviour of the dtml-var "name" attribute. So:
(1) <dtml-var name="x">
gives the same result as
(2) <dtml-var expr="_['x']">
but is not the same as
(3) <dtml-var expr="x">.
For instance, if x is a DTML Method, (1) and (2) execute, or render it, replacing DTML tags within x by their results, and returning plain HTML. Then if you want to access some z attribute of x, you get the dreadful "String object has no attribute z", which tells you that x is no longer a rich object like a folder or a document, but is now a flat string containing the HTML resulting from rendering the x object.
With syntax (3) you just fetch it, which depending on context would display the unrendered DTML code.
If you need to indirectly fetch an object without executing it, you have to use another of _'s methods, getitem. The expression "_.getitem('x')" returns a reference to the object called x, without invoking it.
INDIRECTION
Notice difference between:
(2) <dtml-var expr="_['x']">
(4) <dtml-var expr="_[x]">
These mean COMPLETELY DIFFERENT things. In (2) you want to get the object called 'x' from the namespace dictionary. The key you are using is the string 'x'.
In (4), you are getting the object whose name is stored in variable x. The key, in this case, is whatever is referred by the variable x. If x refers to the string 'ni', then _[x] means _['ni'], that is, fetch the object called 'ni'.
That is why _[x] is called an indirection: in our example you are not fetching 'ni' directly, but indirectly through the x variable. The next time _[x] is evaluated, x may refer to 'sikander', and then _[x] may yield a totally different result.
The same rationale goes for
(5) <dtml-var expr="_.getitem('x')">
(6) <dtml-var expr="_.getitem(x)">
The result of (5) is the same as
(3) <dtml-var expr="x">
so you would never use (5) in real code.
But (6) is useful to fetch an object indirectly without executing it.
AN INTERESTING EXPERIMENT
Try this: within a folder, create two methods with ids 'method1' and 'method2'. Leave 'method2' with its default content, but replace the content of 'method1' with this, then View it.
<dtml-var standard_html_header>
<dtml-var name="method2"> <hr> <dtml-var expr="method2"> <hr> <dtml-var expr="_['method2']"> <hr> <dtml-var expr="_.getitem('method2')">
<dtml-var standard_html_footer>
If my explanations were any good, you should understand what is going on now.
The whole _ issue is why, whenever I teach Zope, I include at least one hour of "instrumental Python". And while playing with the Python interpreter, I always make the students create and do lots of operations with a dictionary called _.
-- Best regards,
Luciano
You should put all of that into a howto! Very well said. -- | Casey Duncan | Kaivo, Inc. | cduncan@kaivo.com `------------------>
participants (3)
-
Casey Duncan -
Luciano Ramalho -
Timothy Wilson