[CMF-checkins] SVN: CMF/branches/2.1/C - changed the way skins are set up, using __before_publishing_traverse__ instead of __of__

Yvo Schubbe y.2007- at wcm-solutions.de
Sun Jun 17 10:08:33 EDT 2007


Log message for revision 76729:
  - changed the way skins are set up, using __before_publishing_traverse__ instead of __of__

Changed:
  U   CMF/branches/2.1/CHANGES.txt
  U   CMF/branches/2.1/CMFCalendar/tests/test_Calendar.py
  U   CMF/branches/2.1/CMFCore/DynamicType.py
  U   CMF/branches/2.1/CMFCore/PortalObject.py
  U   CMF/branches/2.1/CMFCore/Skinnable.py
  U   CMF/branches/2.1/CMFCore/tests/test_SkinsTool.py
  U   CMF/branches/2.1/CMFDefault/tests/RegistrationTool.txt

-=-
Modified: CMF/branches/2.1/CHANGES.txt
===================================================================
--- CMF/branches/2.1/CHANGES.txt	2007-06-17 13:35:02 UTC (rev 76728)
+++ CMF/branches/2.1/CHANGES.txt	2007-06-17 14:08:32 UTC (rev 76729)
@@ -11,6 +11,12 @@
 
   Bug Fixes
 
+    - SkinnableObjectManager: Changed the way skins are set up.
+      Acquisition wrapping no longer triggers 'setupCurrentSkin'. This is now
+      done on publishing traversal after the BeforeTraverseEvent triggers
+      'setSite'. This fix replaces a temporary hack introduced in 2.1.0-beta,
+      making sure ISkinsTool is looked up after setting the site.
+
     - CMFCore.CMFBTreeFolder: CMFBTreeFolders could not be used as the
       toplevel /Members container.
       (http://www.zope.org/Collectors/CMF/441)

Modified: CMF/branches/2.1/CMFCalendar/tests/test_Calendar.py
===================================================================
--- CMF/branches/2.1/CMFCalendar/tests/test_Calendar.py	2007-06-17 13:35:02 UTC (rev 76728)
+++ CMF/branches/2.1/CMFCalendar/tests/test_Calendar.py	2007-06-17 14:08:32 UTC (rev 76729)
@@ -109,6 +109,7 @@
 
     def afterSetUp(self):
         setSite(self.app.site)
+        self.app.site.setupCurrentSkin(self.app.REQUEST)
         newSecurityManager(None, UnrestrictedUser('god', '', ['Manager'], ''))
 
         # sessioning setup

Modified: CMF/branches/2.1/CMFCore/DynamicType.py
===================================================================
--- CMF/branches/2.1/CMFCore/DynamicType.py	2007-06-17 13:35:02 UTC (rev 76728)
+++ CMF/branches/2.1/CMFCore/DynamicType.py	2007-06-17 14:08:32 UTC (rev 76729)
@@ -19,11 +19,10 @@
 
 from AccessControl import ClassSecurityInfo
 from Globals import InitializeClass
-
-from zope.app.publication.zopepublication import BeforeTraverseEvent
+from zope.app.publisher.browser import queryDefaultViewName
 from zope.component import getUtility
+from zope.component import queryMultiAdapter
 from zope.component import queryUtility
-from zope.event import notify
 from zope.interface import implements
 
 from interfaces import IDynamicType
@@ -31,8 +30,6 @@
 from interfaces import IURLTool
 from interfaces.Dynamic import DynamicType as z2IDynamicType
 
-from zope.component import queryMultiAdapter
-from zope.app.publisher.browser import queryDefaultViewName
 
 class DynamicType:
 
@@ -89,7 +86,7 @@
         else:
             msg = 'Action "%s" not available for %s' % (
                         action_chain, '/'.join(self.getPhysicalPath()))
-            raise ValueError(msg) 
+            raise ValueError(msg)
 
     # Support for dynamic icons
 
@@ -124,8 +121,6 @@
         # XXX hack around a bug(?) in BeforeTraverse.MultiHook
         REQUEST = arg2 or arg1
 
-        notify(BeforeTraverseEvent(self, REQUEST))
-
         if REQUEST['REQUEST_METHOD'] not in ('GET', 'POST'):
             return
 

Modified: CMF/branches/2.1/CMFCore/PortalObject.py
===================================================================
--- CMF/branches/2.1/CMFCore/PortalObject.py	2007-06-17 13:35:02 UTC (rev 76728)
+++ CMF/branches/2.1/CMFCore/PortalObject.py	2007-06-17 14:08:32 UTC (rev 76729)
@@ -21,7 +21,9 @@
 from five.localsitemanager.registry import PersistentComponents
 from Globals import InitializeClass
 from Products.Five.component.interfaces import IObjectManagerSite
+from zope.app.publication.zopepublication import BeforeTraverseEvent
 from zope.component.globalregistry import base
+from zope.event import notify
 from zope.interface import implements
 
 from interfaces import ISiteRoot
@@ -44,7 +46,6 @@
 
     # Ensure certain attributes come from the correct base class.
     __getattr__ = SkinnableObjectManager.__getattr__
-    __of__ = SkinnableObjectManager.__of__
     _checkId = SkinnableObjectManager._checkId
 
     # Ensure all necessary permissions exist.
@@ -73,4 +74,16 @@
             self._components.__parent__ = self
         return self._components
 
+    def __before_publishing_traverse__(self, arg1, arg2=None):
+        """ Pre-traversal hook.
+        """
+        # XXX hack around a bug(?) in BeforeTraverse.MultiHook
+        REQUEST = arg2 or arg1
+
+        notify(BeforeTraverseEvent(self, REQUEST))
+        self.setupCurrentSkin(REQUEST)
+
+        super(PortalObjectBase,
+              self).__before_publishing_traverse__(arg1, arg2)
+
 InitializeClass(PortalObjectBase)

Modified: CMF/branches/2.1/CMFCore/Skinnable.py
===================================================================
--- CMF/branches/2.1/CMFCore/Skinnable.py	2007-06-17 13:35:02 UTC (rev 76728)
+++ CMF/branches/2.1/CMFCore/Skinnable.py	2007-06-17 14:08:32 UTC (rev 76729)
@@ -25,7 +25,6 @@
 
 from AccessControl import ClassSecurityInfo
 from Acquisition import aq_base
-from Acquisition import ImplicitAcquisitionWrapper
 from Globals import InitializeClass
 from OFS.ObjectManager import ObjectManager
 from ZODB.POSException import ConflictError
@@ -47,7 +46,7 @@
     except AttributeError:
         superGetAttr = None
 
-_marker = []  # Create a new marker object.
+_MARKER = object()  # Create a new marker object.
 
 
 SKINDATA = {} # mapping thread-id -> (skinobj, skinname, ignore, resolve)
@@ -90,8 +89,8 @@
                 if not ignore.has_key(name):
                     if resolve.has_key(name):
                         return resolve[name]
-                    subob = getattr(ob, name, _marker)
-                    if subob is not _marker:
+                    subob = getattr(ob, name, _MARKER)
+                    if subob is not _MARKER:
                         # Return it in context of self, forgetting
                         # its location and acting as if it were located
                         # in self.
@@ -110,11 +109,6 @@
         """
         skinob = None
         sf = queryUtility(ISkinsTool)
-        if sf is None:
-            # XXX: Maybe we can set up the skin *after* the sm?
-            # try again with self as explicit site
-            sm = getSiteManager(self)
-            sf = sm.queryUtility(ISkinsTool)
 
         if sf is not None:
            if name is not None:
@@ -130,16 +124,12 @@
     def getSkinNameFromRequest(self, REQUEST=None):
         '''Returns the skin name from the Request.'''
         sf = queryUtility(ISkinsTool)
-        if sf is None:
-            # XXX: Maybe we can set up the skin *after* the sm?
-            # try again with self as explicit site
-            sm = getSiteManager(self)
-            sf = sm.queryUtility(ISkinsTool)
+
         if sf is not None:
             return REQUEST.get(sf.getRequestVarname(), None)
 
     security.declarePublic('changeSkin')
-    def changeSkin(self, skinname):
+    def changeSkin(self, skinname, REQUEST=_MARKER):
         '''Change the current skin.
 
         Can be called manually, allowing the user to change
@@ -149,7 +139,11 @@
         if skinobj is not None:
             tid = get_ident()
             SKINDATA[tid] = (skinobj, skinname, {}, {})
-            REQUEST = getattr(self, 'REQUEST', None)
+            if REQUEST is _MARKER:
+                REQUEST = getattr(self, 'REQUEST', None)
+                warn("changeSkin should be called with 'REQUEST' as second "
+                     "argument. The BBB code will be removed in CMF 2.3.",
+                     DeprecationWarning, stacklevel=2)
             if REQUEST is not None:
                 REQUEST._hold(SkinDataCleanup(tid))
 
@@ -177,15 +171,18 @@
             del SKINDATA[tid]
 
     security.declarePublic('setupCurrentSkin')
-    def setupCurrentSkin(self, REQUEST=None):
+    def setupCurrentSkin(self, REQUEST=_MARKER):
         '''
         Sets up skindata so that __getattr__ can find it.
 
         Can NOT be called manually to change skins in the middle of a
         request! Use changeSkin for that.
         '''
-        if REQUEST is None:
+        if REQUEST is _MARKER:
             REQUEST = getattr(self, 'REQUEST', None)
+            warn("setupCurrentSkin should be called with 'REQUEST' as "
+                 "argument. The BBB code will be removed in CMF 2.3.",
+                 DeprecationWarning, stacklevel=2)
         if REQUEST is None:
             # self is not fully wrapped at the moment.  Don't
             # change anything.
@@ -194,23 +191,14 @@
             # Already set up for this request.
             return
         skinname = self.getSkinNameFromRequest(REQUEST)
-        self.changeSkin(skinname)
-
-    def __of__(self, parent):
-        '''
-        Sneakily sets up the portal skin then returns the wrapper
-        that Acquisition.Implicit.__of__() would return.
-        '''
-        w_self = ImplicitAcquisitionWrapper(self, parent)
         try:
-            w_self.setupCurrentSkin()
+            self.changeSkin(skinname, REQUEST)
         except ConflictError:
             raise
         except:
             # This shouldn't happen, even if the requested skin
             # does not exist.
             logger.exception("Unable to setupCurrentSkin()")
-        return w_self
 
     def _checkId(self, id, allow_dup=0):
         '''

Modified: CMF/branches/2.1/CMFCore/tests/test_SkinsTool.py
===================================================================
--- CMF/branches/2.1/CMFCore/tests/test_SkinsTool.py	2007-06-17 13:35:02 UTC (rev 76728)
+++ CMF/branches/2.1/CMFCore/tests/test_SkinsTool.py	2007-06-17 14:08:32 UTC (rev 76729)
@@ -129,7 +129,7 @@
         self.failUnless(som.getCurrentSkinName() == 'skinA')
 
         # after a changeSkin the new skin name should be returned
-        som.changeSkin('skinB')
+        som.changeSkin('skinB', som.REQUEST)
         self.failUnless(som.getCurrentSkinName() == 'skinB')
         
 

Modified: CMF/branches/2.1/CMFDefault/tests/RegistrationTool.txt
===================================================================
--- CMF/branches/2.1/CMFDefault/tests/RegistrationTool.txt	2007-06-17 13:35:02 UTC (rev 76728)
+++ CMF/branches/2.1/CMFDefault/tests/RegistrationTool.txt	2007-06-17 14:08:32 UTC (rev 76729)
@@ -32,6 +32,7 @@
     >>> from Products.CMFCore.interfaces import IMembershipTool
     >>> from Products.MailHost.interfaces import IMailHost
     >>> setSite(app.site)
+    >>> app.site.setupCurrentSkin(app.REQUEST)
     >>> sm = getSiteManager()
     >>> sm.registerUtility(MembershipTool(), IMembershipTool)
     >>> sm.registerUtility(MailHost(), IMailHost)



More information about the CMF-checkins mailing list