[CMF-checkins] CVS: CMF/CMFCore - DynamicType.py:1.17 PortalFolder.py:1.47 TypesTool.py:1.56 utils.py:1.42

Yvo Schubbe schubbe@web.de
Sat, 28 Jun 2003 12:31:51 -0400


Update of /cvs-repository/CMF/CMFCore
In directory cvs.zope.org:/tmp/cvs-serv21800/CMFCore

Modified Files:
	DynamicType.py PortalFolder.py TypesTool.py utils.py 
Log Message:
Merged yuppie-ti_aliases-branch:
- Added Method Aliases to TypeInformation.
- Added __before_publishing_traverse__ to DynamicType.
- Made PortalFolder's 'mkdir' hook an alias.

=== CMF/CMFCore/DynamicType.py 1.16 => 1.17 ===
--- CMF/CMFCore/DynamicType.py:1.16	Thu Feb 13 03:28:42 2003
+++ CMF/CMFCore/DynamicType.py	Sat Jun 28 12:31:20 2003
@@ -93,4 +93,21 @@
     security.declarePublic('icon')
     icon = getIcon  # For the ZMI
 
+    def __before_publishing_traverse__(self, arg1, arg2=None):
+        """ Pre-traversal hook.
+        """
+        # XXX hack around a bug(?) in BeforeTraverse.MultiHook
+        REQUEST = arg2 or arg1
+
+        stack = REQUEST['TraversalRequestNameStack']
+        key = stack and stack[-1] or '(Default)'
+        ti = self.getTypeInfo()
+        path = ti and ti.getMethodPath(key) or None
+        if path:
+            if key is not '(Default)':
+                stack.pop()
+            for id in path:
+                if id is not '(Default)':
+                    stack.append(id)
+
 InitializeClass(DynamicType)


=== CMF/CMFCore/PortalFolder.py 1.46 => 1.47 ===
--- CMF/CMFCore/PortalFolder.py:1.46	Fri May  9 17:40:23 2003
+++ CMF/CMFCore/PortalFolder.py	Sat Jun 28 12:31:20 2003
@@ -41,6 +41,9 @@
   , 'factory'        : 'manage_addPortalFolder'
   , 'filter_content_types' : 0
   , 'immediate_view' : 'folder_edit_form'
+  , 'aliases'        : {'(Default)':'index_html',
+                        'view':'index_html',
+                        'index.html':'index_html'}
   , 'actions'        : ( { 'id'            : 'view'
                          , 'name'          : 'View'
                          , 'action': 'string:${object_url}'
@@ -464,20 +467,18 @@
                         , title=''
                         , REQUEST=None
                         ):
+        """ Add a new folder-like object with id *id*.
+
+        IF present, use the parent object's 'mkdir' alias; otherwise, just add
+        a PortalFolder.
         """
-            Add a new folder-like object with id *id*.  IF present,
-            use the parent object's 'mkdir' action;  otherwise, just
-            add a PortalFolder.
-            to take control of the process by checking for a 'mkdir'
-            action.
-        """
-        try:
-            action = self.getTypeInfo().getActionById( 'mkdir' )
-        except ValueError:
-            self.invokeFactory( type_name='Folder', id=id )
-        else:
+        ti = self.getTypeInfo()
+        method = ti and ti.getMethodURL('mkdir') or None
+        if method:
             # call it
-            getattr( self, action )( id=id )
+            getattr(self, method)(id=id)
+        else:
+            self.invokeFactory( type_name='Folder', id=id )
 
         ob = self._getOb( id )
         ob.setTitle( title )


=== CMF/CMFCore/TypesTool.py 1.55 => 1.56 ===
--- CMF/CMFCore/TypesTool.py:1.55	Wed Jun 11 07:11:18 2003
+++ CMF/CMFCore/TypesTool.py	Sat Jun 28 12:31:20 2003
@@ -25,6 +25,7 @@
 from Acquisition import aq_get
 from zLOG import LOG, WARNING, ERROR
 from OFS.Folder import Folder
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
 import Products
 
 from interfaces.portal_types import ContentTypeInformation as ITypeInformation
@@ -40,6 +41,7 @@
 from utils import SimpleItemWithProperties
 from utils import _dtmldir
 from utils import _checkPermission
+from utils import _wwwdir
 from utils import cookString
 from utils import getActionContext
 
@@ -53,11 +55,12 @@
     _isTypeInformation = 1
 
     manage_options = ( SimpleItemWithProperties.manage_options[:1]
+                     + ( {'label':'Aliases',
+                          'action':'manage_aliases'}, )
                      + ActionProviderBase.manage_options
                      + SimpleItemWithProperties.manage_options[1:]
                      )
 
-
     security = ClassSecurityInfo()
 
     security.declareProtected(ManagePortal, 'manage_editProperties')
@@ -145,7 +148,35 @@
                           , visible=action.get( 'visible', 1 )
                           )
 
+        aliases = kw.get( 'aliases', _marker )
+        if aliases is _marker:
+            self._guessMethodAliases()
+        else:
+            self.setMethodAliases(aliases)
+
+    #
+    #   ZMI methods
+    #
+    security.declareProtected(ManagePortal, 'manage_aliases')
+    manage_aliases = PageTemplateFile( 'typeinfoAliases.zpt', _wwwdir )
+
+    security.declareProtected(ManagePortal, 'manage_setMethodAliases')
+    def manage_setMethodAliases(self, REQUEST):
+        """ Config method aliases.
+        """
+        form = REQUEST.form
+        aliases = {}
+        for k, v in form['aliases'].items():
+            v = v.strip()
+            if v:
+                aliases[k] = v
         
+        dict = {}
+        for k, v in form['methods'].items():
+            if aliases.has_key(k):
+                dict[ aliases[k] ] = v
+        self.setMethodAliases(dict)
+        REQUEST.RESPONSE.redirect('%s/manage_aliases' % self.absolute_url())
 
     #
     #   Accessors
@@ -312,6 +343,102 @@
 
         return ob
 
+    security.declareProtected(ManagePortal, 'getMethodAliases')
+    def getMethodAliases(self):
+        """ Get method aliases dict.
+        """
+        if not hasattr(self, '_aliases'):
+            self._guessMethodAliases()
+        dict = {}
+        aliases = self._aliases
+        for k, v in aliases.items():
+            path = list(v)
+            path.reverse()
+            dict[k] = '/'.join(path)
+        return dict
+
+    security.declareProtected(ManagePortal, 'setMethodAliases')
+    def setMethodAliases(self, aliases):
+        """ Set method aliases dict.
+        """
+        dict = {}
+        for k, v in aliases.items():
+            v = v.strip()
+            if v:
+                path = v.split('/')
+                path.reverse()
+                dict[ k.strip() ] = tuple(path)
+        if not getattr(self, '_aliases', None) == dict:
+            self._aliases = dict
+            return 1
+        else:
+            return 0
+
+    security.declarePublic('getMethodPath')
+    def getMethodPath(self, key):
+        """ Get reverse relative method path by alias.
+        """
+        if not hasattr(self, '_aliases'):
+            self._guessMethodAliases()
+        aliases = self._aliases
+        return aliases.get( key, () )
+
+    security.declarePublic('getMethodURL')
+    def getMethodURL(self, key):
+        """ Get relative method URL by alias.
+        """
+        path = list( self.getMethodPath(key) )
+        path.reverse()
+        return '/'.join(path)
+
+    security.declarePrivate('_guessMethodAliases')
+    def _guessMethodAliases(self):
+        """ Guess and set Method Aliases. Used for upgrading old TIs.
+        """
+        context = getActionContext(self)
+        actions = self.listActions()
+        ordered = []
+        dict = {}
+
+        # order actions and search 'mkdir' action 
+        for action in actions:
+            if action.getId() == 'view':
+                ordered.insert(0, action)
+            elif action.getId() == 'mkdir':
+                mkdirmethod = action.action(context).strip()
+                if mkdirmethod.startswith('/'):
+                    mkdirmethod = mkdirmethod[1:]
+                dict['mkdir'] = mkdirmethod
+            else:
+                ordered.append(action)
+
+        # search 'view' action
+        for action in ordered:
+            perms = action.getPermissions()
+            if not perms or View in perms:
+                viewmethod = action.action(context).strip()
+                if viewmethod.startswith('/'):
+                    viewmethod = viewmethod[1:]
+                if not viewmethod:
+                    viewmethod = '(Default)'
+                break
+        else:
+            viewmethod = '(Default)'
+        dict['view'] = viewmethod
+
+        # search default action
+        for action in ordered:
+            defmethod = action.action(context).strip()
+            if defmethod.startswith('/'):
+                defmethod = defmethod[1:]
+            if not defmethod:
+                break
+        else:
+            dict['(Default)'] = viewmethod
+
+        self.setMethodAliases(dict)
+        return 1
+
 InitializeClass( TypeInformation )
 
 
@@ -508,11 +635,14 @@
 
     security = ClassSecurityInfo()
 
-    manage_options = ( Folder.manage_options +
-                      ActionProviderBase.manage_options +
-                      ({ 'label' : 'Overview', 'action' : 'manage_overview' }
-                     , 
-                     ))
+    manage_options = ( Folder.manage_options[:1]
+                     + ( {'label':'Aliases',
+                          'action':'manage_aliases'}, )
+                     + ActionProviderBase.manage_options
+                     + ( {'label':'Overview',
+                          'action':'manage_overview'}, )
+                     + Folder.manage_options[1:]
+                     )
 
     #
     #   ZMI methods
@@ -520,6 +650,9 @@
     security.declareProtected(ManagePortal, 'manage_overview')
     manage_overview = DTMLFile( 'explainTypesTool', _dtmldir )
 
+    security.declareProtected(ManagePortal, 'manage_aliases')
+    manage_aliases = PageTemplateFile( 'typesAliases.zpt', _wwwdir )
+
     def all_meta_types(self):
         """Adds TypesTool-specific meta types."""
         all = TypesTool.inheritedAttribute('all_meta_types')(self)
@@ -618,6 +751,25 @@
         if RESPONSE is not None:
             RESPONSE.redirect('%s/manage_main' % self.absolute_url())
 
+    security.declareProtected(ManagePortal, 'manage_setTIMethodAliases')
+    def manage_setTIMethodAliases(self, REQUEST):
+        """ Config method aliases.
+        """
+        form = REQUEST.form
+        aliases = {}
+        for k, v in form['aliases'].items():
+            v = v.strip()
+            if v:
+                aliases[k] = v
+        
+        for ti in self.listTypeInfo():
+            dict = {}
+            for k, v in form[ ti.getId() ].items():
+                if aliases.has_key(k):
+                    dict[ aliases[k] ] = v
+            ti.setMethodAliases(dict)
+        REQUEST.RESPONSE.redirect('%s/manage_aliases' % self.absolute_url())
+
     security.declareProtected(AccessContentsInformation, 'getTypeInfo')
     def getTypeInfo( self, contentType ):
         """
@@ -737,5 +889,18 @@
                 actions.extend( type_info.listActions( info ) )
 
         return actions
+
+    security.declareProtected(ManagePortal, 'listMethodAliasKeys')
+    def listMethodAliasKeys(self):
+        """ List all defined method alias names.
+        """
+        dict = {}
+        for ti in self.listTypeInfo():
+            aliases = ti.getMethodAliases()
+            for k, v in aliases.items():
+                dict[k] = 1
+        rval = dict.keys()
+        rval.sort()
+        return rval
 
 InitializeClass( TypesTool )


=== CMF/CMFCore/utils.py 1.41 => 1.42 ===
--- CMF/CMFCore/utils.py:1.41	Mon Jun 23 08:21:42 2003
+++ CMF/CMFCore/utils.py	Sat Jun 28 12:31:20 2003
@@ -49,6 +49,7 @@
 security = ModuleSecurityInfo( 'Products.CMFCore.utils' )
 
 _dtmldir = os_path.join( package_home( globals() ), 'dtml' )
+_wwwdir = os.path.join( package_home( globals() ), 'www' )
 
 #
 #   Simple utility functions, callable from restricted code.