On Tue, Sep 12, 2000 at 10:57:57AM -0700, Brett Carter wrote:
"Shane" == Shane Hathaway <shane@digicool.com> writes:
Shane> Brett Carter wrote: >> >>>>> "Brett" == Brett Carter <brett@kavi.com> writes: >> Brett> I've defined my own dtml tag (i.e. <dtml-foo></dtml-foo>) Brett> and I am trying to look up an object depending on the Brett> arguments passed to my tag. The python class that defines Brett> the tag inherits from Acquisition.Implicit, but 'self' Brett> doesn't contain any of the Acquisition hiarchy. It seems Brett> like this must be possible, since the <dtml-var> tag must Brett> have to do an object lookup somewhere for objects passed to Brett> it to render. Can anybody shed some light on this? Is it Brett> doable? TIA -Brett >> Ok, So after some *major* hacking, i've realized that the 'md' >> passed into the render() method of my dtml tag contains the >> namespace, and is of type 'TemplateDict' which appears to >> contain a stack of 'MultiMapping's. Weird. Well, anyways, I >> just used the 'has_key' and 'getitem' methods to lookup my >> item. The question now is how do I create a new object in the >> current namespace? It looks like the TemplateDict is a >> read-only type of data structure. Anybody? TIA -Brett
Shane> Look at render() of DT_With.py. It does an Shane> md._push(<mapping containing new names>) then, in a Shane> try/finally clause, calls DT_Util.render_blocks(). In the Shane> finally clause, it does md._pop().
Shane> Shane
I'm still confused. Ok, so render gets passed 'md', which is a TemplateDict, which contains a MultiMapping, which looks like a stack of dictionaries, which I am guessing is some sort of namespace stack. So looking at the DT_with.py, it looks like, to create an object in the current namespace, I have to wrap it in an InstanceDict, and push it onto the 'md' using 'md._push'. Does this also cause the new object to be saved in the ZODB? Or do I have to manually add it there too? Also, what does render_blocks do? Why does DT_with.py's render() return it? Do I have to run render_blocks() to insert my new object into the namespace? TIA
There are two seperate things here: The namespace, and the ZODB. I am assuming you want to add an object to the ZODB. The namespace reflects, amongst others, the attributes on the current object, and if it inherits from Acquisition.Implicit, the rest of the ZODB contents. You can add additional lookup objects to that stack, and anything using the namespace can then access those extra attributes. (render_blocks() is just a call to render all DTML contained within the with tag, and the with tag then removes all additions to the namespace again with md._pop() at the end.) If you want to manipulate the ZODB, you can just take a reference to the object you want to manipulate (add subobjects to), and add these directly as attributes. Or better still, if the object inherits from ObjectManager (like a Folder), use the ObjectManager API to add objects. If the subobjects in question are standard Zope objects, use the Class Factory API that the 'Add' list in the management interface uses. Important to remember is here that the namespace only gives you access to the objetcs. Adding to the namespace only gives you a larger namespace, which only has meaning in the context of the current DTML code tree. If you want to manipulate the ZODB contained objects, manipulate them directly. -- 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 -----------------------------------------------------