[Checkins] SVN: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/ Working PublishTraversal adapter
Matthew Wilkes
matthew at matthewwilkes.co.uk
Sun Aug 16 16:14:55 EDT 2009
Log message for revision 102862:
Working PublishTraversal adapter
Changed:
U Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py
U Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/configure.zcml
U Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/interfaces/_tools.py
A Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/traverser.py
-=-
Modified: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py
===================================================================
--- Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py 2009-08-16 19:22:43 UTC (rev 102861)
+++ Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/Skinnable.py 2009-08-16 20:14:54 UTC (rev 102862)
@@ -29,6 +29,8 @@
from ZODB.POSException import ConflictError
from zope.interface import implements
+from interfaces import ISkinnableObjectManager
+
logger = logging.getLogger('CMFCore.Skinnable')
Modified: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/configure.zcml
===================================================================
--- Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/configure.zcml 2009-08-16 19:22:43 UTC (rev 102861)
+++ Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/configure.zcml 2009-08-16 20:14:54 UTC (rev 102862)
@@ -13,4 +13,10 @@
<include file="tool.zcml"/>
+ <adapter
+ factory = ".traverser.PortalRootPublishTraverse"
+ for = ".interfaces.ISkinnableObjectManager zope.interface.Interface"
+ />
+
+
</configure>
Modified: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/interfaces/_tools.py
===================================================================
--- Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/interfaces/_tools.py 2009-08-16 19:22:43 UTC (rev 102861)
+++ Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/interfaces/_tools.py 2009-08-16 20:14:54 UTC (rev 102862)
@@ -1248,12 +1248,12 @@
o Permission: Public
"""
-class ISkinnableObjectManager(object):
+class ISkinnableObjectManager(Interface):
""" An object that has skins applied to it."""
- def __getattr__(self, name):
+ def __getattr__(name):
'''
Looks for the name in an object with wrappers that only reach
up to the root skins folder.
@@ -1261,28 +1261,28 @@
This should be fast, flexible, and predictable.
'''
- def getSkin(self, name=None):
+ def getSkin(name):
"""Returns the requested skin.
"""
- def getSkinNameFromRequest(self, REQUEST=None):
+ def getSkinNameFromRequest(REQUEST):
'''Returns the skin name from the Request.'''
- def changeSkin(self, skinname, REQUEST=_MARKER):
+ def changeSkin(skinname, REQUEST):
'''Change the current skin.
Can be called manually, allowing the user to change
skins in the middle of a request.
'''
- def getCurrentSkinName(self):
+ def getCurrentSkinName():
'''Return the current skin name.
'''
- def clearCurrentSkin(self):
+ def clearCurrentSkin():
"""Clear the current skin."""
- def setupCurrentSkin(self, REQUEST=_MARKER):
+ def setupCurrentSkin(REQUEST):
'''
Sets up skindata so that __getattr__ can find it.
Added: Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/traverser.py
===================================================================
--- Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/traverser.py (rev 0)
+++ Products.CMFCore/branches/matthewwilkes-traversalprecedence/Products/CMFCore/traverser.py 2009-08-16 20:14:54 UTC (rev 102862)
@@ -0,0 +1,110 @@
+##############################################################################
+#
+# Copyright (c) 2001, 2002, 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""CMF portal traverser
+
+$Id: traverser.py 67630 2006-04-27 00:54:03Z jim $
+"""
+__docformat__ = 'restructuredtext'
+
+from zExceptions import Forbidden
+
+from Acquisition.interfaces import IAcquirer
+
+from zope.interface import implements, Interface
+from zope.component import queryMultiAdapter
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from ZPublisher.BaseRequest import DefaultPublishTraverse, typeCheck
+
+class PortalRootPublishTraverse(DefaultPublishTraverse):
+
+ implements(IBrowserPublisher)
+
+ def publishTraverse(self, request, name):
+ object = self.context
+ URL=request['URL']
+
+
+ if name[:1]=='_':
+ raise Forbidden("Object name begins with an underscore at: %s" % URL)
+
+
+ if hasattr(object,'__bobo_traverse__'):
+ # We can use the normal logic
+ return super(PortalRootPublishTraverse, self).publishTraverse(request, name)
+ else:
+
+ subobject = None
+
+ # No __bobo_traverse__
+ # Try with an unacquired attribute:
+ try:
+ subobject = object.__getattribute__(name).aq_base.__of__(object)
+ except AttributeError:
+ # this is not a direct object
+ pass
+
+
+ if subobject is None:
+ # We try to fall back to a view:
+ subobject = queryMultiAdapter((object, request), Interface,
+ name)
+ if subobject is not None:
+ if IAcquirer.providedBy(subobject):
+ subobject = subobject.__of__(object)
+ return subobject
+
+ # And lastly, of there is no view, try acquired attributes, but
+ # only if there is no __bobo_traverse__:
+ try:
+ subobject=getattr(object, name)
+ # Again, clear any error status created by __bobo_traverse__
+ # because we actually found something:
+ request.response.setStatus(200)
+ return subobject
+ except AttributeError:
+ pass
+
+ # Lastly we try with key access:
+ try:
+ subobject = object[name]
+ except TypeError: # unsubscriptable
+ raise KeyError(name)
+
+
+ # Ensure that the object has a docstring, or that the parent
+ # object has a pseudo-docstring for the object. Objects that
+ # have an empty or missing docstring are not published.
+ doc = getattr(subobject, '__doc__', None)
+ if doc is None:
+ doc = getattr(object, '%s__doc__' % name, None)
+ if not doc:
+ raise Forbidden(
+ "The object at %s has an empty or missing " \
+ "docstring. Objects must have a docstring to be " \
+ "published." % URL
+ )
+
+ # Hack for security: in Python 2.2.2, most built-in types
+ # gained docstrings that they didn't have before. That caused
+ # certain mutable types (dicts, lists) to become publishable
+ # when they shouldn't be. The following check makes sure that
+ # the right thing happens in both 2.2.2+ and earlier versions.
+
+ if not typeCheck(subobject):
+ raise Forbidden(
+ "The object at %s is not publishable." % URL
+ )
+
+ return subobject
More information about the Checkins
mailing list