[Zope] Problem with _[xyz]
Martijn Pieters
mj@digicool.com
Fri, 7 Jul 2000 21:01:16 +0200
On Fri, Jul 07, 2000 at 07:12:26PM +0200, Christian Zagrodnick wrote:
> shouldn't <dtml-var xyz> and <dtml-var "_['xyz']"> return the same result?
>
> Well - I don't know why but only the 1st is working.
> (top.German.ActualPages is a folder; tThisIs... is a dtml-method)
>
> 1:
> <dtml-with "top.German.ActualPages">
> <dtml-var tThisIsTheXYZDocument>
> </dtml-with>
>
>
> 2:
> <dtml-with "_['top.German.ActualPages']">
> <dtml-var tThisIsTheXYZDocument>
> </dtml-with>
>
>
> Of course I want to replace the 'top.German.ActualPages' with a variable...
> but since it doesn't work with a hardcoded string it'll not work with a
> variable.
Two things wrong here:
1. <dtml-var expr="xyz"> is not the same as <dtml-var expr="_['xyz']"> if xyz is
callable! <dtml-var name="xyz"> (or <dtml-var xyz>) however is.
_[] will call the identified object if it can be. You can use
_.getitem('xyz', 0) (or just plain _.getitem('xyz')) to get an item without
calling it. Calling _.getitem('xyz', 1) (second argument 'true') is the
same as _['xyz'] and <dtml-var xyz> again.
2. top.German.ActualPages is a Python expression meaning "The 'ActualPages'
object in the 'German' object inside the 'top' object. The '.' operator
signifies containment or membership.
_['top.German.ActualPages'] however, means "The 'top.German.ActualPages'
object", where the dots are part of the identifier. You want to split this
name up at the dots, and ask the namespace for each part individually, like
_['top']['German']['ActualPages'].
Now, using a variable, this is going to be a bit more tricky. If it is all the
same to you, you may want to change such an object pointer to use '/' instead
of '.' as an object delimiter, and use the new Zope 2.2.0 Traversal interface
for this. If you have to, you use _.string.replace to replace all dots with
slashes on the spot. For this interface, see:
http://www.zope.org/Members/michel/Projects/Interfaces/Traversal
Note that this interface is restricted to Product and External Method access
only! You will have to create yourself a Eternal Method in this case:
import string
getObject(self, id):
if string.find(id, '.'): id = string.split(id, '.')
return self.restrictedTraverse(id)
The above method will support id's with both dots and slashes, but not id's
that have a '.' in them (like 'image.gif').
Use this method then like this:
<dtml-with "getObject(id)">
<dtml-var tThisIsTheXYZDocument>
</dtml-with>
--
Martijn Pieters
| Software Engineer mailto:mj@digicool.com
| Digital Creations http://www.digicool.com/
| Creators of Zope http://www.zope.org/
| ZopeStudio: http://www.zope.org/Products/ZopeStudio
-----------------------------------------------------