[Zope-Checkins] SVN: Zope/branches/philikon-aq/lib/python/Products/Five/browser/ The existing two absolute_url adapter implementations are specifically geared

Philipp von Weitershausen philikon at philikon.de
Sat Jul 28 21:48:18 EDT 2007


Log message for revision 78451:
  The existing two absolute_url adapter implementations are specifically geared
  towards OFS.Traversable and OFS.Application. Name them so.
  
  Introduce a more generic implementation that's very very close to the Zope 3
  one and works on objects that don't inherit from OFS.Traversable or support
  acquisition (e.g. views, resources, etc.)
  

Changed:
  U   Zope/branches/philikon-aq/lib/python/Products/Five/browser/absoluteurl.py
  U   Zope/branches/philikon-aq/lib/python/Products/Five/browser/configure.zcml
  U   Zope/branches/philikon-aq/lib/python/Products/Five/browser/tests/test_absoluteurl.py

-=-
Modified: Zope/branches/philikon-aq/lib/python/Products/Five/browser/absoluteurl.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/Products/Five/browser/absoluteurl.py	2007-07-29 00:43:22 UTC (rev 78450)
+++ Zope/branches/philikon-aq/lib/python/Products/Five/browser/absoluteurl.py	2007-07-29 01:48:18 UTC (rev 78451)
@@ -15,26 +15,89 @@
 
 $Id$
 """
+import urllib
 from Acquisition import aq_inner, aq_parent
 from OFS.interfaces import ITraversable
 
 from zope.interface import implements
 from zope.component import getMultiAdapter
 from zope.traversing.browser.interfaces import IAbsoluteURL
+from zope.traversing.browser.absoluteurl import _insufficientContext, _safe
 
 from Products.Five.browser import BrowserView
 
 class AbsoluteURL(BrowserView):
-    """An adapter for Zope3-style absolute_url using Zope2 methods
+    """An absolute_url adapter for generic objects in Zope 2 that
+    aren't OFS.Traversable (e.g. views, resources, etc.).
 
-    (original: zope.traversing.browser.absoluteurl)
+    This is very close to the generic implementation from
+    zope.traversing.browser, but the Zope 2 request doesn't support
+    all the methods that it uses yet.
     """
     implements(IAbsoluteURL)
 
-    def __init__(self, context, request):
-        self.context, self.request = context, request
+    def __unicode__(self):
+        return urllib.unquote(self.__str__()).decode('utf-8')
 
     def __str__(self):
+        context = self.context
+        request = self.request
+
+        container = aq_parent(context)
+        if container is None:
+            raise TypeError(_insufficientContext)
+
+        url = str(getMultiAdapter((container, request), name='absolute_url'))
+        name = self._getContextName(context)
+        if name is None:
+            raise TypeError(_insufficientContext)
+
+        if name:
+            url += '/' + urllib.quote(name.encode('utf-8'), _safe)
+
+        return url
+
+    __call__ = __str__
+
+    def _getContextName(self, context):
+        if getattr(context, 'getId', None) is not None:
+            return context.getId()
+        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
+        container = aq_parent(context)
+        if container is None:
+            raise TypeError(_insufficientContext)
+
+        base = tuple(getMultiAdapter((container, request),
+                                     name='absolute_url').breadcrumbs())
+
+        name = self._getContextName(context)
+        if name is None:
+            raise TypeError(_insufficientContext)
+
+        if name:
+            base += ({'name': name,
+                      'url': ("%s/%s" % (base[-1]['url'],
+                                         urllib.quote(name.encode('utf-8'),
+                                                      _safe)))
+                      }, )
+
+        return base
+
+class OFSTraversableAbsoluteURL(BrowserView):
+    """An absolute_url adapter for OFS.Traversable subclasses
+    """
+    implements(IAbsoluteURL)
+
+    def __unicode__(self):
+        return urllib.unquote(self.__str__()).decode('utf-8')
+
+    def __str__(self):
         context = aq_inner(self.context)
         return context.absolute_url()
 
@@ -47,10 +110,10 @@
 
         name = context.getId()
         
-        if container is None or self._isVirtualHostRoot() \
-            or not ITraversable.providedBy(container):
-            return (
-                {'name': name, 'url': context.absolute_url()},)
+        if (container is None
+            or self._isVirtualHostRoot()
+            or not ITraversable.providedBy(container)):
+            return ({'name': name, 'url': context.absolute_url()},)
 
         view = getMultiAdapter((container, request), IAbsoluteURL)
         base = tuple(view.breadcrumbs())
@@ -66,15 +129,9 @@
         context = aq_inner(self.context)
         return context.restrictedTraverse(virtualrootpath) == context
 
-class SiteAbsoluteURL(AbsoluteURL):
-    """An adapter for Zope3-style absolute_url using Zope2 methods
-
-    This one is just used to stop breadcrumbs from crumbing up
-    to the Zope root.
-
-    (original: zope.traversing.browser.absoluteurl)
+class RootAbsoluteURL(OFSTraversableAbsoluteURL):
+    """An absolute_url adapter for the root object (OFS.Application)
     """
-
     def breadcrumbs(self):
         context = self.context
         request = self.request

Modified: Zope/branches/philikon-aq/lib/python/Products/Five/browser/configure.zcml
===================================================================
--- Zope/branches/philikon-aq/lib/python/Products/Five/browser/configure.zcml	2007-07-29 00:43:22 UTC (rev 78450)
+++ Zope/branches/philikon-aq/lib/python/Products/Five/browser/configure.zcml	2007-07-29 01:48:18 UTC (rev 78451)
@@ -39,21 +39,37 @@
       />
 
   <browser:page
-      for="zope.traversing.interfaces.IContainmentRoot"
+      for="OFS.interfaces.ITraversable"
       name="absolute_url"
-      class=".absoluteurl.SiteAbsoluteURL"
+      class=".absoluteurl.OFSTraversableAbsoluteURL"
       permission="zope.Public"
       allowed_interface="zope.traversing.browser.interfaces.IAbsoluteURL"
       />
 
   <view
-      for="zope.traversing.interfaces.IContainmentRoot"
-      factory=".absoluteurl.SiteAbsoluteURL"
+      for="OFS.interfaces.ITraversable"
+      factory=".absoluteurl.OFSTraversableAbsoluteURL"
       type="zope.publisher.interfaces.http.IHTTPRequest"
       permission="zope.Public"
       provides="zope.traversing.browser.interfaces.IAbsoluteURL"
       />
 
+  <browser:page
+      for="OFS.interfaces.IApplication"
+      name="absolute_url"
+      class=".absoluteurl.RootAbsoluteURL"
+      permission="zope.Public"
+      allowed_interface="zope.traversing.browser.interfaces.IAbsoluteURL"
+      />
+
+  <view
+      for="OFS.interfaces.IApplication"
+      factory=".absoluteurl.RootAbsoluteURL"
+      type="zope.publisher.interfaces.http.IHTTPRequest"
+      permission="zope.Public"
+      provides="zope.traversing.browser.interfaces.IAbsoluteURL"
+      />
+
   <browser:view
       for="OFS.interfaces.IObjectManager"
       name="+"

Modified: Zope/branches/philikon-aq/lib/python/Products/Five/browser/tests/test_absoluteurl.py
===================================================================
--- Zope/branches/philikon-aq/lib/python/Products/Five/browser/tests/test_absoluteurl.py	2007-07-29 00:43:22 UTC (rev 78450)
+++ Zope/branches/philikon-aq/lib/python/Products/Five/browser/tests/test_absoluteurl.py	2007-07-29 01:48:18 UTC (rev 78451)
@@ -51,12 +51,11 @@
 
     This test assures and demonstrates that the absolute url stops
     traversing through an object's parents when it has reached the
-    root object.  In Zope 3 this is marked with the IContainmentRoot
-    interface:
+    root object.
 
-      >>> from zope.interface import directlyProvides, providedBy
-      >>> from zope.traversing.interfaces import IContainmentRoot
-      >>> directlyProvides(self.folder, IContainmentRoot)
+      >>> from zope.interface import alsoProvides, noLongerProvides
+      >>> from OFS.interfaces import IApplication
+      >>> alsoProvides(self.folder, IApplication)
 
       >>> for crumb in view.breadcrumbs():
       ...     info = crumb.items()
@@ -65,8 +64,7 @@
       [('name', 'test_folder_1_'), ('url', 'http://nohost/test_folder_1_')]
       [('name', 'testoid'), ('url', 'http://nohost/test_folder_1_/testoid')]
 
-      >>> directlyProvides(self.folder,
-      ...                  providedBy(self.folder) - IContainmentRoot)
+      >>> noLongerProvides(self.folder, IApplication)
 
     The absolute url view is obviously not affected by virtual hosting:
 



More information about the Zope-Checkins mailing list