[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