[Checkins] SVN: zope.traversing/trunk/src/zope/traversing/browser/ Improved the AbsoluteURL traverser so that it always attempts to adapt

Brandon Rhodes brandon at rhodesmill.org
Wed Sep 19 10:32:43 EDT 2007


Log message for revision 79750:
  Improved the AbsoluteURL traverser so that it always attempts to adapt
  its context to ILocation before attempting to access __parent__ and
  __name__, in case these are provided by an adapter instead of residing
  on the context object itself.
  

Changed:
  U   zope.traversing/trunk/src/zope/traversing/browser/absoluteurl.py
  U   zope.traversing/trunk/src/zope/traversing/browser/tests.py

-=-
Modified: zope.traversing/trunk/src/zope/traversing/browser/absoluteurl.py
===================================================================
--- zope.traversing/trunk/src/zope/traversing/browser/absoluteurl.py	2007-09-19 14:20:02 UTC (rev 79749)
+++ zope.traversing/trunk/src/zope/traversing/browser/absoluteurl.py	2007-09-19 14:32:43 UTC (rev 79750)
@@ -18,6 +18,7 @@
 import urllib
 import zope.component
 from zope.interface import implements
+from zope.location.interfaces import ILocation
 from zope.proxy import sameProxiedObjects
 from zope.publisher.browser import BrowserView
 from zope.traversing.browser.interfaces import IAbsoluteURL
@@ -50,13 +51,14 @@
             or sameProxiedObjects(context, request.getVirtualHostRoot())):
             return request.getApplicationURL()
 
+        context = ILocation(context, context)
         container = getattr(context, '__parent__', None)
         if container is None:
             raise TypeError(_insufficientContext)
 
         url = str(zope.component.getMultiAdapter((container, request),
                                                  name='absolute_url'))
-        name = self._getContextName(context)
+        name = getattr(context, '__name__', None)
         if name is None:
             raise TypeError(_insufficientContext)
 
@@ -67,14 +69,12 @@
 
     __call__ = __str__
 
-    def _getContextName(self, context):
-        return getattr(context, '__name__', None)
-
     def breadcrumbs(self):
         context = self.context
         request = self.request
 
         # We do this here do maintain the rule that we must be wrapped
+        context = ILocation(context, context)
         container = getattr(context, '__parent__', None)
         if container is None:
             raise TypeError(_insufficientContext)

Modified: zope.traversing/trunk/src/zope/traversing/browser/tests.py
===================================================================
--- zope.traversing/trunk/src/zope/traversing/browser/tests.py	2007-09-19 14:20:02 UTC (rev 79749)
+++ zope.traversing/trunk/src/zope/traversing/browser/tests.py	2007-09-19 14:32:43 UTC (rev 79750)
@@ -18,7 +18,7 @@
 from unittest import TestCase, main, makeSuite
 
 import zope.component
-from zope.component import getMultiAdapter
+from zope.component import getMultiAdapter, adapts
 from zope.traversing.browser.absoluteurl import absoluteURL
 from zope.traversing.browser.interfaces import IAbsoluteURL
 from zope.traversing.testing import browserView
@@ -27,6 +27,7 @@
 from zope.interface.verify import verifyObject
 from zope.publisher.browser import TestRequest
 from zope.publisher.http import IHTTPRequest, HTTPCharsets
+from zope.location.interfaces import ILocation
 
 from zope.app.container.contained import contained
 from zope.app.testing import setup
@@ -41,6 +42,25 @@
 class TrivialContent(object):
     """Trivial content object, used because instances of object are rocks."""
 
+class FooContent(object):
+    """Class whose location will be provided by an adapter."""
+
+class FooLocation(object):
+    """Adapts FooAdapter to the ILocation protocol."""
+    implements(ILocation)
+    adapts(FooContent)
+
+    def __init__(self, context):
+        self.context = context
+
+    @property
+    def __name__(self):
+        return 'foo'
+
+    @property
+    def __parent__(self):
+        return contained(TrivialContent(), Root(), name='bar')
+
 class TestAbsoluteURL(TestCase):
 
     def setUp(self):
@@ -50,6 +70,7 @@
         browserView(IRoot, 'absolute_url', SiteAbsoluteURL)
         browserView(None, '', AbsoluteURL, providing=IAbsoluteURL)
         browserView(IRoot, '', SiteAbsoluteURL, providing=IAbsoluteURL)
+        zope.component.provideAdapter(FooLocation)
         zope.component.provideAdapter(HTTPCharsets, (IHTTPRequest,),
                                       IUserPreferredCharsets)
 
@@ -94,6 +115,22 @@
                           {'name': 'c', 'url': 'http://127.0.0.1/a/b/c'},
                           ))
 
+    def testAdaptedContext(self):
+        request = TestRequest()
+
+        content = FooContent()
+        view = getMultiAdapter((content, request), name='absolute_url')
+        self.assertEqual(str(view), 'http://127.0.0.1/bar/foo')
+        self.assertEqual(absoluteURL(content, request),
+                         'http://127.0.0.1/bar/foo')
+
+        breadcrumbs = view.breadcrumbs()
+        self.assertEqual(breadcrumbs,
+                         ({'name':  '', 'url': 'http://127.0.0.1'},
+                          {'name': 'bar', 'url': 'http://127.0.0.1/bar'},
+                          {'name': 'foo', 'url': 'http://127.0.0.1/bar/foo'},
+                          ))
+
     def testBasicContext_unicode(self):
         #Tests so that AbsoluteURL handle unicode names as well
         request = TestRequest()



More information about the Checkins mailing list