I'm using Zope 2.5.1b1, CMF from CVS. I'm having a strange problem when trying to define a custom __bobo_traverse__, where an Unauthorized exception is raised from PageTemplates/Expressions.py/restrictedTraverse. The object's __bobo_traverse__ is simply doing def __bobo_traverse__(self, REQUEST, name): """Traversal to get to the virtual documents.""" target = getattr(self, name, None) if target is not None: return target #... other things that are never called ... (The goal would be to make some objects appear to be under a given level which isn't in fact a container but calls the catalog to display a listing.) With that code, if I try to view the object, I get: ... File .../lib/python/ZPublisher/Publish.py, line 39, in call_object (Object: foo) File .../Products/CMFCore/PortalContent.py, line 167, in __call__ (Object: foo) File .../lib/python/Shared/DC/Scripts/Bindings.py, line 252, in __call__ (Object: mylevel_view) File .../lib/python/Shared/DC/Scripts/Bindings.py, line 283, in _bindAndExec (Object: mylevel_view) File .../lib/python/Products/PageTemplates/Expressions.py, line 177, in _eval File .../lib/python/Products/PageTemplates/Expressions.py, line 134, in _eval (Info: here) File .../lib/python/Products/PageTemplates/Expressions.py, line 321, in restrictedTraverse (Object: foo) (Info: {'path': ['portal_url'], 'TraversalRequestNameStack': []}) Unauthorized: You are not allowed to access portal_url in this context There error stems from the fact that the view calls here/portal_url, which sould be ok. If I remove the bobo_traverse, everything works fine and dandy of course. I don't undersand the difference because my __bobo_traverse__ is just doing standard stuff that traversal would do anyway. If I look at Expressions.py/restrictedTraverse, there are discrepancies I cannot explain. The relevant parts in this case are (I commented the code that's not executed, for display purposes): t=get(object, '__bobo_traverse__', N) if t is not N: o=t(REQUEST, name) container = None #if has(o, 'im_self'): # container = o.im_self #elif (has(get(object, 'aq_base', object), name) # and get(object, name) == o): # container = object if not validate(object, container, name, o): raise Unauthorized, name # line 321 else: o=get(object, name, M) if o is not M: # Check security. if has(object, 'aq_acquire'): object.aq_acquire( name, validate2, validate) #else: # if not validate(object, object, name, o): # raise Unauthorized, name #else: # try: # o=object[name] # except (AttributeError, TypeError): # raise AttributeError, name # if not validate(object, object, name, o): # raise Unauthorized, name object = o So I don't understand the different treatments, with bobo_traverse I get a None container, which makes the validate fail, whereas standard traversal calls ac_acquire with as a filter validate2, the filters receives a container, and this validation suceeds. If anybody has any lights on how I write do the __bobo_traverse__ I need... Thanks, Florent -- Florent Guillaume, Nuxeo (Paris, France) +33 1 40 33 79 10 http://nuxeo.com mailto:fg@nuxeo.com