[Zope] Use of lambda expression in DTML

Duncan Booth duncan@rcp.co.uk
Tue, 30 May 2000 10:13:10 +0000


> In brief: I get a NameError when invoking "filter(...)" from DTML.  I thought this was a built-in python method, so I'm a bit puzzled.

Python's ideas of 'built-in' is simply any method in the module 
stored in the global variable called __builtins__. Any code executed 
with a non-standard global variable space may or may not have the 
same set of builtins as normal Python code.

Unfortunately Zope does not expose all of the 'builtin' python 
methods to DMTL expressions. Some obviously need to be cut out 
(such as 'open') for security reasons, but the reasons why others 
were dropped are less obvious.

If you really need any of the missing builtins back in you have a 
couple of choices. Both require you have full access to your Zope 
system.

If you want the function available throughout your Zope system 
simply edit DocumentTemplate\DT_Util.py. Look for the list 
beginning 'None', 'abs', 'chr' and simply add 'filter' into the list.

Alternatively if you dont want to patch Zope directly, create an 
external python method that exposes filter.

> 5) In the dtml-tree tag, I change it to:
> 
> 	<dtml-tree 
> 		Technical 
> 		leaves=dtcTemplate 
> 		branches_expr="filter( lambda f: not f.hasProperty('blockTreeBranching', false), objectValues(['Folder']) )">
> 
> which, all things equal, should DoTheRightThang.

Even if you make the filter function visible as described above, this 
still won't quite work. For example the method 'objectValues' is not 
in scope within the function. The way around this is to pass in an 
extra parameter _vars. Try (untested):

branches_expr="filter( lambda f, _vars=_vars: not 
f.hasProperty('blockTreeBranching', 0), objectValues(['Folder']) )">  

and it might work.

Alternatively use something like a PythonMethod, or even a DTML 
method and simply write the filter loop out in full using 'for' or 'dtml-
in'.

-- 
Duncan Booth                                             duncan@dales.rmplc.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?
http://dales.rmplc.co.uk/Duncan