[Zope3-Users] Re: Traversal Tricks (was Seeking Reference Guide on
	TAL/TALES/METAL)
    Jeff Rush 
    jeff at taupro.com
       
    Sat Apr  1 07:16:27 EST 2006
    
    
  
Jeff Rush wrote:
> 
> My specific question is how evaluation of the path expression "X/Z" is 
> handled.  It *seems* to be:
> 
>     X.__getitem__('Y')    # X['Y']
> 
> whereas I'm trying to get:
> 
>     X.__getattr__('Y')    # X.Y
> 
> Under Zope 2, as I recall, it would try several algorithms; attribute, 
> mapping, sequence.  And I'm wondering if that mechanism was simplified 
> for Zope 3, and in what way.
Study has shown that it searches attribute then item namespace for 
non-containers, *but* item and then attribute namespace for containers.
My objects are "contained" containers representing specialized SQL tables 
(records are items), that also themselves have attributes.  So the search of 
item namespace first was causing bogus (and time consuming) SQL queries to 
be made.
I need control over which namespace is searched, so I added a couple of 
generic TALES namespace adapters.  Now I can do:
   <h1 tal:content="context/attr:name" />
to -only- search for a name attribute, and (less frequently):
   <h1 tal:content="context/item:ABC123" />
to -only- search using __getitem__() calls.
Perhaps this is useful to others, and since it wasn't much code, here it is:
---- cut here ----
_marker = object()
 
 
class AttrPathAdapter(object):
     """Only search attribute not item namespace for path members."""
 
 
     implements(ITALESFunctionNamespace)
 
 
     def __init__(self, context):
         self.context = context
 
 
     def setEngine(self, engine):
         self.locale = removeSecurityProxy(engine.vars['request']).locale
 
 
     def __getattribute__(self, name):
         if name.startswith("_"):
             return super(AttrPathAdapter, self).__getattribute__(name)
         value = getattr(self.__dict__['context'], name, _marker)
         if value is _marker:
             return super(AttrPathAdapter, self).__getattribute__(name)
         return value
 
 
class ItemPathAdapter(object):
     """Only search item not attribute namespace for path members."""
 
 
     implements(ITALESFunctionNamespace)
 
 
     def __init__(self, context):
         self.context = context
 
 
     def setEngine(self, engine):
         self.locale = removeSecurityProxy(engine.vars['request']).locale
 
 
     def __getattribute__(self, name):
         if name.startswith("_"):
             return super(ItemPathAdapter, self).__getattribute__(name)
         value = self.__dict__['context'].get(name, _marker)
         if value is _marker:
             return super(ItemPathAdapter, self).__getattribute__(name)
         return value
 
 
        ---- cut here ----
   <adapter
       factory="webaccountant.pathadapters.AttrPathAdapter"
 
 
       provides="zope.app.traversing.interfaces.IPathAdapter"
       for="*"
       name="attr"
       />
 
 
   <adapter
       factory="webaccountant.pathadapters.ItemPathAdapter"
 
 
       provides="zope.app.traversing.interfaces.IPathAdapter"
       for="*"
       name="item"
       />
 
 
---- cut here ----
-Jeff
    
    
More information about the Zope3-users
mailing list