[Zope-CMF] Re: [dev] Actions: lazy dict not working with DTML?
yuppie
y.2004_ at wcm-solutions.de
Wed Aug 4 05:21:12 EDT 2004
Hi!
Dieter Maurer wrote:
> yuppie wrote at 2004-8-2 18:21 +0200:
>
>>Since last week listFilteredActionsFor() returns ActionInfo objects
>>instead of dictionaries. I tried to implement ActionInfo as a lazy dict
>>to defer expensive processing of TALES expressions.
>
> What is a lazy dict?
Maybe there is a better term for this. I use 'lazy' in analogy to how it
is used in ZCatalog/Lazy.py or ZPublisher/HTTPRequest.py. I mean a dict
that computes (some of) its values on demand, avoiding the need to
compute them on creation time.
The ActionInfo class is checked in here:
<http://cvs.zope.org/CMF/CMFCore/ActionInformation.py?rev=1.24&content-type=text/vnd.viewcvs-markup>
Basically this is a dict with a customized __getitem__ method.
>>This seems to work with the ZPT skin, but not with the old DTML skin.
>>
>> <dtml-in user_actions mapping>
>> <a href="&dtml-url;"><dtml-var name></a><br>
>> </dtml-in>
>>
>>Looks like this code bypasses __getitem__, but I don't understand how
>>this works because I'm not a C programmer and can't read the
>>TemplateDict code.
>
>
> This is unlikely.
>
> With the "mapping" keyword, the object itself is pushed
> onto the "TemplateDict" (it is a stack of namespaces);
> without it, it is wrapped before pushing into a "ClientDict" (I think)
> which maps "__getitem__" to "__getattr__".
>
> The "TemplateDict"s "getitem" asks each namespace on its stack
> for the name using its "__getitem__" until it succeeds or reaches
> the end of the stack.
>
> When you send me a code fragment showing how your
> "lazy dict" looks and works in principle, I can try to
> analyse the problem.
Great. I attached an unittest that shows the problem. While
pDocumentTemplate seems to implement TemplateDict based on a
MultiMapping, MultiMapping works as expected. So cDocumentTemplate seems
to do something different.
If this is not easy to resolve, I'll check in my workaround for
listFilteredActionsFor. I guess we can live with that.
Thanks,
Yuppie
-------------- next part --------------
from unittest import TestCase, TestSuite, makeSuite, main
import Testing
import Zope
Zope.startup()
from DocumentTemplate.DT_Util import TemplateDict
from MultiMapping import MultiMapping
class LazyDict(dict):
def __getitem__(self, key):
return 'bar'
class LazyDictTests(TestCase):
def test_LazyDict(self):
ld = LazyDict(foo='foo')
self.assertEqual(ld['foo'], 'bar')
def test_inMultiMapping(self):
ld = LazyDict(foo='foo')
mm = MultiMapping()
mm.push(ld)
self.assertEqual(mm['foo'], 'bar')
def test_inTemplateDict(self):
ld = LazyDict(foo='foo')
td = TemplateDict()
td._push(ld)
self.assertEqual(td['foo'], 'bar')
def test_suite():
return TestSuite((
makeSuite(LazyDictTests),
))
if __name__ == '__main__':
main(defaultTest='test_suite')
More information about the Zope-CMF
mailing list