[z3-checkins] r5678 - z3/Five/branch/dc-experiments

dreamcatcher at codespeak.net dreamcatcher at codespeak.net
Mon Jul 26 13:08:44 MEST 2004


Author: dreamcatcher
Date: Mon Jul 26 13:08:44 2004
New Revision: 5678

Added:
   z3/Five/branch/dc-experiments/traversable.py   (contents, props changed)
Log:

- Add Traversable mixin, based on previous Viewable
- Add FiveTraversable ITraversable adapter



Added: z3/Five/branch/dc-experiments/traversable.py
==============================================================================
--- (empty file)
+++ z3/Five/branch/dc-experiments/traversable.py	Mon Jul 26 13:08:44 2004
@@ -0,0 +1,91 @@
+##############################################################################
+#
+# Copyright (c) 2004 Five Contributors. All rights reserved.
+#
+# This software is distributed under the terms of the Zope Public
+# License (ZPL) v2.1. See COPYING.txt for more information.
+#
+##############################################################################
+"""Machinery for making things traversable through adaptation
+
+$Id: traversable.py 5654 2004-07-24 20:35:55Z dreamcatcher $
+"""
+from zope.exceptions import NotFoundError
+from zope.component import getView, ComponentLookupError
+from zope.interface import implements
+from zope.publisher.interfaces.browser import IBrowserRequest
+from zope.app.traversing.interfaces import ITraverser, ITraversable
+from zope.app.traversing.adapters import DefaultTraversable
+from zope.app.traversing.namespace import queryResourceInContext
+from monkey import DebugFlags
+
+class FakeRequest:
+    implements(IBrowserRequest)
+
+    debug = DebugFlags()
+
+    def getPresentationSkin(self):
+        return None
+
+class Traversable:
+    """A mixin to make an object traversable using an ITraverser adapter.
+    """
+    __five_traversable__ = True
+
+    def __fallback_traverse__(self, REQUEST, name):
+        """Method hook for fallback traversal
+
+        This method is called by __bobo_traverse___ when Zope3-style
+        ITraverser traversal fails. By default, we do what Zope 2 would do,
+        raise a NotFound error.
+        """
+        try:
+            REQUEST.RESPONSE.notFoundError("%s " % name)
+        except AttributeError:
+            raise KeyError, name
+
+    def __bobo_traverse__(self, REQUEST, name):
+        """Hook for Zope 2 traversal
+
+        This method is called by Zope 2's ZPublisher upon traversal.
+        It allows us to trick it into faking the Zope 3 traversal system
+        by using an ITraverser adapter.
+        """
+        if not IBrowserRequest.providedBy(REQUEST):
+            REQUEST = FakeRequest()
+        try:
+            kw = dict(path=[name], request=REQUEST)
+            return ITraverser(self).traverse(**kw).__of__(self)
+        except (ComponentLookupError, NotFoundError, AttributeError):
+            pass
+        try:
+            return getattr(self, name)
+        except AttributeError:
+            pass
+        try:
+            return self[name]
+        except (AttributeError, KeyError):
+            pass
+        return self.__fallback_traverse__(REQUEST, name)
+
+class FiveTraversable(DefaultTraversable):
+
+    def traverse(self, name, furtherPath):
+        context = self._subject
+        __traceback_info__ = (context, name, furtherPath)
+        # Find the REQUEST
+        REQUEST = getattr(context, 'REQUEST', None)
+        if not IBrowserRequest.providedBy(REQUEST):
+            REQUEST = FakeRequest()
+        # Try to lookup a view first
+        try:
+            return getView(context, name, REQUEST).__of__(context)
+        except ComponentLookupError:
+            pass
+        # If a view can't be found, try to lookup a resource
+        resource = queryResourceInContext(context, name, REQUEST)
+        if resource is not None:
+            return resource
+        # If a resource can't be found, then use default traversable
+        return super(FiveTraversable, self).traverse(name, furtherPath)
+


More information about the z3-checkins mailing list