[Joseph A Knapka]>
Stupid question of the day:
Why might the following code result in a KeyError? It does in some contexts under Zope 2.5.0.
<dtml-if expr="REQUEST.has_key('xyz')"> <dtml-else> <dtml-call expr="REQUEST.set('xyz','Hello world')"> </dtml-if>
Sometimes the next line results in a KeyError, value 'xyz':
<dtml-var name="xyz">
In such cases, this works fine:
<dtml-with REQUEST only> <dtml-var name="xyz"> </dtml-with>
You set the property named "xyz" in the REQUEST, and you can be sure of referring to it if you say "REQUEST['xyz'] or "REQUEST.xyz", as in <dtml-var "REQUEST['xyz']"> Note that using "expr=" is redundant - you can always omit it. So your example could be written: <dtml-if "REQUEST.has_key('xyz')"> <dtml-else> <dtml-call "REQUEST.set('xyz','Hello world')"> </dtml-if> or, a bit simpler and more readable, <dtml-if "not REQUEST.has_key('xyz')"> <dtml-call "REQUEST.set('xyz','Hello world')"> </dtml-if> Referring to "REQUEST['xyz']" always works. But as long as no other namespace has been inserted into the mix, you can also get the value in any of these ways: 1) <dtml-var "xyz"> 2) <dtml-var xyz> 3) <dtml-var "_['xyz']> That's because REQUEST properties are specially made available to its owner's namespace for convenience. These last three versions all really ask for the same thing, just in slightly different ways: 1) asks for a Python variable named "xyz". Python looks for this variable in the namespace stack, which normally starts with the namepace of the dtml document containing the code (if it is in a dtml document, otherwise different rules apply). 2) asks Zope for a variable named "xyz". Zope looks in its namespace stack to find it. It's normally the same namespace stack that Python would be using, so this is equivalent to 1) in most cases. 3) is an alternative way to ask for the same thing as 2). It's advantage is that the name of the variable does not have to be known when you write the code - any string will do. If the code is in a dtml method, the method does not have its own namespace. What namespace it uses, and therefore whether it can find the right variable, depends on how it is called, thus the results can vary. There have been many threads in the list about this. Cheers, Tom P