[CMF-checkins] CVS: CMF/CMFCore - ActionInformation.py:1.2 ActionProviderBase.py:1.2 Expression.py:1.2 ActionsTool.py:1.20 CatalogTool.py:1.22 MemberDataTool.py:1.13 MembershipTool.py:1.17 PortalFolder.py:1.29 RegistrationTool.py:1.8 SkinsTool.py:1.12 TypesTool.py:1.27 UndoTool.py:1.5 WorkflowTool.py:1.20
Andrew Sawyers
andrew@zope.com
Fri, 4 Jan 2002 14:50:35 -0500
Update of /cvs-repository/CMF/CMFCore
In directory cvs.zope.org:/tmp/cvs-serv10417/CMFCore
Modified Files:
ActionsTool.py CatalogTool.py MemberDataTool.py
MembershipTool.py PortalFolder.py RegistrationTool.py
SkinsTool.py TypesTool.py UndoTool.py WorkflowTool.py
Added Files:
ActionInformation.py ActionProviderBase.py Expression.py
Log Message:
*Merging andrew_ttw_actions-branch into the head
*Adds TTW configuration of Action Providers
*Allows tools to have actions managed TTW
*Added unittests for ActionTool, ActionInformation, and
Expression
*Added TTW action management to all stock CMF tools
*Added Expression module for allowing actions and conditions of
actions to be TALES.
=== CMF/CMFCore/ActionInformation.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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
+#
+##############################################################################
+
+"""Basic action list tool.
+
+$Id$
+"""
+__version__='$Revision$'[11:-2]
+
+from utils import SimpleItemWithProperties, _dtmldir, getToolByName
+import CMFCorePermissions
+from AccessControl import ClassSecurityInfo
+from Acquisition import aq_inner, aq_parent
+from Globals import InitializeClass, DTMLFile
+
+class ActionInformation(SimpleItemWithProperties):
+ """
+ Represent a single action which the user can select from a list
+ and execut in some context.
+ """
+ _isActionInformation = 1
+ __allow_access_to_unprotected_subobjects__ = 1
+
+ manage_options = (SimpleItemWithProperties.manage_options[:1] +
+ ({'label': 'Actions',
+ 'action': 'manage_editActionsForm'},) +
+ SimpleItemWithProperties.manage_options[1:])
+ security = ClassSecurityInfo()
+ security.declareProtected(CMFCorePermissions.ManagePortal
+ , 'manage_editProperties'
+ , 'manage_changeProperties'
+ , 'manage_propertiesForm'
+ )
+
+ _basic_properties = (
+ {'id': 'title', 'type': 'string', 'mode': 'w', 'label': 'Title'}
+ , {'id': 'description', 'type': 'text', 'mode': 'w',
+ 'label': 'Description'}
+ , {'id': 'category', 'type': 'string', 'mode': 'w',
+ 'label': 'Category'}
+ , {'id': 'priority', 'type': 'boolean', 'mode': 'w', 'label': 'Priority'}
+ )
+
+ title = ''
+ description = ''
+ category = ''
+ priority = 0
+ visible = 1
+ _action = ''
+
+ def __init__(self
+ , id
+ , title=''
+ , description=''
+ , category='object'
+ , condition=''
+ , permissions=()
+ , priority=10
+ , visible=1
+ , action=''):
+ """
+ Setup an instance
+ """
+ self.id = id
+ self.title = title
+ self.description = description
+ self.category = category
+ self.condition = condition
+ self.permissions = permissions
+ self.priority = priority
+ self.visible = visible
+ self._action = action
+
+
+ security.declareProtected(CMFCorePermissions.View, 'Title')
+ def Title(self):
+ """
+ Return the Action title - name
+ """
+ if self.title:
+ return self.title
+ else:
+ return self.getId()
+
+ security.declareProtected(CMFCorePermissions.View, 'Description')
+ def Description(self):
+ """
+ Return a description of the action
+ """
+ return self.description
+
+ security.declarePrivate('testCondition')
+ def testCondition(self, ec):
+ """
+ Evaluate condition and return 0 or 1
+ """
+ if self.condition:
+ return self.condition(ec)
+ else:
+ return 1
+
+ security.declarePublic('getAction')
+ def getAction(self, ec):
+ """
+ Return the action, which is an TALES expresssion
+ """
+ if self._action:
+ aa = self._action(ec)
+ else:
+ aa = ''
+ action = {}
+ action['id'] = self.id
+ action['name'] = self.Title()
+ action['url'] = aa
+ action['permissions'] = self.getPermissions()
+ action['category'] = self.getCategory()
+ action['visible'] = self.getVisibility()
+ return action
+
+ security.declarePublic('getActionExpression')
+ def getActionExpression(self):
+ """
+ If not an empty string or None, return the
+ text of the expression otherwise return ''
+ """
+ if self._action:
+ return self._action.text
+ else:
+ return self._action
+
+ security.declarePublic('getCondition')
+ def getCondition(self):
+ """
+ If not an empty string or None, return the
+ text of the expression otherwise
+ return ''
+ """
+ if self.condition:
+ return self.condition.text
+ else:
+ return self.condition
+
+ security.declarePublic('getPermission')
+ def getPermissions(self):
+ """
+ Return the permission if any required for a user to
+ execute the action
+ """
+ return self.permissions
+
+ security.declarePublic('getCategory')
+ def getCategory(self):
+ """
+ Return the category for which the action is
+ """
+ if self.category:
+ return self.category
+ else:
+ return 'object'
+
+ security.declarePublic('getVisibility')
+ def getVisibility(self):
+ """
+ Return boolean for whether the action
+ is visible in the UI
+ """
+ return self.visible
+
+ security.declarePublic('getPriority')
+ def getPriority(self):
+ """
+ Return integer priority for sorting
+ Not used....keep and implement or toss?
+ """
+ if self.priority:
+ return self.priority
+ else:
+ return 10
+
+InitializeClass(ActionInformation)
+
+class oai:
+ #Provided for backwards compatability
+ # Provides information that may be needed when constructing the list of
+ # available actions.
+ __allow_access_to_unprotected_subobjects__ = 1
+
+ def __init__(self, tool, folder, object=None):
+ self.portal = portal = aq_parent(aq_inner(tool))
+ membership = getToolByName(tool, 'portal_membership')
+ self.isAnonymous = membership.isAnonymousUser()
+ self.portal_url = portal.absolute_url()
+ if folder is not None:
+ self.folder_url = folder.absolute_url()
+ self.folder = folder
+ else:
+ self.folder_url = self.portal_url
+ self.folder = portal
+ self.content = object
+ if object is not None:
+ self.content_url = object.absolute_url()
+ else:
+ self.content_url = None
+
+ def __getitem__(self, name):
+ # Mapping interface for easy string formatting.
+ if name[:1] == '_':
+ raise KeyError, name
+ if hasattr(self, name):
+ return getattr(self, name)
+ raise KeyError, name
+
=== CMF/CMFCore/ActionProviderBase.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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
+#
+##############################################################################
+
+from OFS.SimpleItem import SimpleItem
+from Globals import DTMLFile
+from CMFCorePermissions import ManagePortal
+from utils import _dtmldir, cookString
+from AccessControl import ClassSecurityInfo
+from ActionInformation import ActionInformation
+from Expression import Expression
+
+
+"""Basic action list tool.
+
+$Id$
+"""
+__version__='$Revision$'[11:-2]
+
+class ActionProviderBase:
+ """
+ Provide ActionTabs and management methods for ActionProviders
+ """
+ _actions = []
+ security = ClassSecurityInfo()
+ _actions_form = DTMLFile( 'editToolsActions', _dtmldir )
+
+ manage_options = ({ 'label' : 'Actions', 'action' : 'manage_editActionsForm' }
+ ,
+ )
+
+ security.declarePrivate('listActions')
+ def listActions(self):
+ """
+ Return all the actions defined by a tool
+ """
+ if self._actions:
+ return self._actions
+ else:
+ return None
+
+ security.declareProtected(ManagePortal, 'manage_editActionsForm')
+ def manage_editActionsForm(self, REQUEST, manage_tabs_message=None):
+ """
+ Shows the 'Actions' management tab.
+ """
+ actions = []
+ if self.listActions() is not None:
+ for a in self.listActions():
+ a1 = {}
+ a1['id'] = a.getId()
+ a1['name'] = a.Title()
+ p = a.getPermissions()
+ if p:
+ a1['permission'] = p[0]
+ else:
+ a1['permission'] = ''
+ a1['category'] = a.getCategory() or 'object'
+ a1['visible'] = a.getVisibility()
+ if a._action:
+ a1['action'] = a.getActionExpression()
+ else:
+ a1['action'] = ''
+ if a.condition:
+ a1['condition'] = a.getCondition()
+ else:
+ a1['condition'] = ''
+ actions.append(a1)
+ # possible_permissions is in AccessControl.Role.RoleManager.
+ pp = self.possible_permissions()
+ return self._actions_form(self, REQUEST,
+ actions=actions,
+ possible_permissions=pp,
+ management_view='Actions',
+ manage_tabs_message=manage_tabs_message)
+
+ security.declareProtected(ManagePortal, 'addAction')
+ def addAction( self
+ , id
+ , name
+ , action
+ , condition
+ , permission
+ , category
+ , visible=1
+ , REQUEST=None
+ ):
+ """
+ Adds an action to the list.
+ """
+ al = self._actions
+ if not name:
+ raise ValueError('A name is required.')
+ if action:
+ a_expr = Expression(text=str(action))
+ else:
+ a_expr = ''
+ if condition:
+ c_expr = Expression(text=str(condition))
+ else:
+ c_expr = ''
+ al.append(ActionInformation(id=str(id)
+ , title=str(name)
+ , action=a_expr
+ , condition=c_expr
+ , permissions=(str(permission),)
+ , category=str(category)
+ , visible=int(visible)
+ ))
+ self._actions = al
+ if REQUEST is not None:
+ return self.manage_editActionsForm(
+ REQUEST, manage_tabs_message='Added.')
+
+ security.declareProtected(ManagePortal, 'changeActions')
+ def changeActions(self, properties=None, REQUEST=None):
+ """
+ Changes the _actions.
+ """
+ if properties is None:
+ properties = REQUEST
+ actions = []
+ for idx in range(len(self._actions)):
+ s_idx = str(idx)
+ action = {
+ 'id': str(properties.get('id_' + s_idx, '')),
+ 'name': str(properties.get('name_' + s_idx, '')),
+ 'action': str(properties.get('action_' + s_idx, '')),
+ 'condition': str(properties.get('condition_' + s_idx, '')),
+ 'permissions':
+ (properties.get('permission_' + s_idx, ()),),
+ 'category': str(properties.get('category_' + s_idx, 'object')),
+ 'visible': properties.get('visible_' + s_idx, 0),
+ }
+ if not action['name']:
+ raise ValueError('A name is required.')
+ a = self._actions[idx]
+ a.id = action['id']
+ a.title = action['name']
+ if action['action'] is not '':
+ a._action = Expression(text=action['action'])
+ else:
+ a._action = ''
+ if action['condition'] is not '':
+ a.condition = Expression(text=action['condition'])
+ else:
+ a.condition = ''
+ a.permissions = action['permissions']
+ a.category = action['category']
+ a.visible = action['visible']
+ if REQUEST is not None:
+ return self.manage_editActionsForm(REQUEST, manage_tabs_message=
+ 'Actions changed.')
+
+ security.declareProtected(ManagePortal, 'deleteActions')
+ def deleteActions(self, selections=(), REQUEST=None):
+ """
+ Deletes actions.
+ """
+ actions = list(self._actions)
+ sels = list(map(int, selections)) # Convert to a list of integers.
+ sels.sort()
+ sels.reverse()
+ for idx in sels:
+ del actions[idx]
+ self._actions = actions
+ if REQUEST is not None:
+ return self.manage_editActionsForm(
+ REQUEST, manage_tabs_message=(
+ 'Deleted %d action(s).' % len(sels)))
+
+ security.declareProtected(ManagePortal, 'moveUpActions')
+ def moveUpActions(self, selections=(), REQUEST=None):
+ """
+ Moves the specified actions up one slot.
+ """
+ actions = list(self._actions)
+ sels = list(map(int, selections)) # Convert to a list of integers.
+ sels.sort()
+ for idx in sels:
+ idx2 = idx - 1
+ if idx2 < 0:
+ # Wrap to the bottom.
+ idx2 = len(actions) - 1
+ # Swap.
+ a = actions[idx2]
+ actions[idx2] = actions[idx]
+ actions[idx] = a
+ self._actions = actions
+ if REQUEST is not None:
+ return self.manage_editActionsForm(
+ REQUEST, manage_tabs_message=(
+ 'Moved up %d action(s).' % len(sels)))
+
+ security.declareProtected(ManagePortal, 'moveDownActions')
+ def moveDownActions(self, selections=(), REQUEST=None):
+ """
+ Moves the specified actions down one slot.
+ """
+ actions = list(self._actions)
+ sels = list(map(int, selections)) # Convert to a list of integers.
+ sels.sort()
+ sels.reverse()
+ for idx in sels:
+ idx2 = idx + 1
+ if idx2 >= len(actions):
+ # Wrap to the top.
+ idx2 = 0
+ # Swap.
+ a = actions[idx2]
+ actions[idx2] = actions[idx]
+ actions[idx] = a
+ self._actions = actions
+ if REQUEST is not None:
+ return self.manage_editActionsForm(
+ REQUEST, manage_tabs_message=(
+ 'Moved down %d action(s).' % len(sels)))
=== CMF/CMFCore/Expression.py 1.1 => 1.2 ===
+#
+# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (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
+#
+##############################################################################
+'''
+Expressions in a web-configurable workflow.
+$Id$
+'''
+__version__='$Revision$'[11:-2]
+
+import Globals
+from Globals import Persistent
+from Acquisition import aq_inner, aq_parent
+from AccessControl import getSecurityManager, ClassSecurityInfo
+
+from utils import getToolByName
+from Products.PageTemplates.Expressions import getEngine
+from Products.PageTemplates.TALES import SafeMapping
+from Products.PageTemplates.PageTemplate import ModuleImporter
+
+
+class Expression (Persistent):
+ text = ''
+ _v_compiled = None
+
+ security = ClassSecurityInfo()
+
+ def __init__(self, text):
+ self.text = text
+ self._v_compiled = getEngine().compile(text)
+
+ def __call__(self, econtext):
+ compiled = self._v_compiled
+ if compiled is None:
+ compiled = self._v_compiled = getEngine().compile(self.text)
+ # ?? Maybe expressions should manipulate the security
+ # context stack.
+ res = compiled(econtext)
+ if isinstance(res, Exception):
+ raise res
+ #print 'returning %s from %s' % (`res`, self.text)
+ return res
+
+Globals.InitializeClass(Expression)
+
+
+def createExprContext(folder, portal, object):
+ '''
+ An expression context provides names for TALES expressions.
+ '''
+ pm = getToolByName(portal, 'portal_membership')
+ if object is None:
+ object_url = ''
+ else:
+ object_url = object.absolute_url()
+ if pm.isAnonymousUser():
+ member = None
+ else:
+ member = pm.getAuthenticatedMember()
+ data = {
+ 'object_url': object_url,
+ 'folder_url': folder.absolute_url(),
+ 'portal_url': portal.absolute_url(),
+ 'object': object,
+ 'folder': folder,
+ 'portal': portal,
+ 'nothing': None,
+ 'request': getattr( object, 'REQUEST', None ),
+ 'modules': ModuleImporter,
+ 'member': member,
+ }
+ return getEngine().getContext(data)
+
=== CMF/CMFCore/ActionsTool.py 1.19 => 1.20 ===
-from utils import UniqueObject, _getAuthenticatedUser, _checkPermission
-from utils import getToolByName, _dtmldir
+import OFS
+from utils import UniqueObject, SimpleItemWithProperties, _getAuthenticatedUser, _checkPermission
+from utils import getToolByName, _dtmldir, cookString
import CMFCorePermissions
from OFS.SimpleItem import SimpleItem
from Globals import InitializeClass, DTMLFile, package_home
@@ -27,60 +28,57 @@
from Acquisition import aq_base, aq_inner, aq_parent
from AccessControl import ClassSecurityInfo
from string import join
+from Expression import Expression, createExprContext
+from ActionInformation import ActionInformation, oai
+from ActionProviderBase import ActionProviderBase
-class ActionInformation:
- # Provides information that may be needed when constructing the list of
- # available actions.
- __allow_access_to_unprotected_subobjects__ = 1
-
- def __init__(self, tool, folder, object=None):
- self.portal = portal = aq_parent(aq_inner(tool))
- membership = getToolByName(tool, 'portal_membership')
- self.isAnonymous = membership.isAnonymousUser()
- self.portal_url = portal.absolute_url()
- if folder is not None:
- self.folder_url = folder.absolute_url()
- self.folder = folder
- else:
- self.folder_url = self.portal_url
- self.folder = portal
- self.content = object
- if object is not None:
- self.content_url = object.absolute_url()
- else:
- self.content_url = None
- def __getitem__(self, name):
- # Mapping interface for easy string formatting.
- if name[:1] == '_':
- raise KeyError, name
- if hasattr(self, name):
- return getattr(self, name)
- raise KeyError, name
-
-
-class ActionsTool (UniqueObject, SimpleItem):
+class ActionsTool(UniqueObject, OFS.Folder.Folder, ActionProviderBase):
"""
Weave together the various sources of "actions" which are apropos
to the current user and context.
"""
id = 'portal_actions'
+ _actions = [ActionInformation(id='folderContents'
+ , title='Folder contents'
+ , action=Expression(
+ text='string: ${folder_url}/folder_contents')
+ , condition=Expression(
+ text='python: folder is not object')
+ , permissions=('List folder contents',)
+ , category='object'
+ , visible=1
+ )
+ , ActionInformation(id='folderContents'
+ , title='Folder contents'
+ , action=Expression(
+ text='string: ${folder_url}/folder_contents')
+ , condition=Expression(
+ text='python: folder is object')
+ , permissions=('List folder contents',)
+ , category='folder'
+ , visible=1
+ )]
+
meta_type = 'CMF Actions Tool'
- action_providers = ( 'portal_actions'
- , 'portal_memberdata'
- , 'portal_registration'
- , 'portal_discussion'
- , 'portal_membership'
- , 'portal_workflow'
- , 'portal_undo'
- )
+ action_providers = ('portal_membership'
+ , 'portal_actions'
+ , 'portal_registration'
+ , 'portal_discussion'
+ , 'portal_undo'
+ , 'portal_syndication'
+ , 'portal_workflow'
+ , 'portal_properties')
security = ClassSecurityInfo()
- manage_options = ( { 'label' : 'Overview', 'action' : 'manage_overview' }
- ,
- ) + SimpleItem.manage_options
+ manage_options = ( ActionProviderBase.manage_options +
+ ({'label' : 'Action Providers', 'action' : 'manage_actionProviders'}
+ , { 'label' : 'Overview', 'action' : 'manage_overview' }
+ ,
+ ) + OFS.Folder.Folder.manage_options
+ )
#
# ZMI methods
@@ -88,19 +86,55 @@
security.declareProtected( CMFCorePermissions.ManagePortal
, 'manage_overview' )
manage_overview = DTMLFile( 'explainActionsTool', _dtmldir )
+ manage_actionProviders = DTMLFile('manageActionProviders', _dtmldir)
#
# Programmatically manipulate the list of action providers
#
+ security.declarePrivate('listActions')
+ def listActions(self, info=None):
+ """
+ Lists actions available through the tool.
+ """
+ return self._actions
+
security.declareProtected( CMFCorePermissions.ManagePortal
, 'listActionProviders'
)
- def listActionProviders( self ):
+ def listActionProviders(self):
""" returns a sequence of action providers known by this tool """
return self.action_providers
+ security.declareProtected(CMFCorePermissions.ManagePortal
+ , 'manage_aproviders')
+ def manage_aproviders(self
+ , apname=''
+ , chosen=()
+ , add_provider=0
+ , del_provider=0
+ , REQUEST=None):
+ """
+ Manage TTW Action Providers
+ """
+ providers = list(self.listActionProviders())
+ new_providers = []
+ if add_provider:
+ providers.append(apname)
+ elif del_provider:
+ for item in providers:
+ if item not in chosen:
+ new_providers.append(item)
+ providers = new_providers
+ self.action_providers = providers
+ if REQUEST is not None:
+ return self.manage_actionProviders(self
+ , REQUEST
+ , manage_tabs_message='Properties changed.')
+
+
+
security.declareProtected( CMFCorePermissions.ManagePortal
, 'addActionProvider'
)
@@ -111,26 +145,6 @@
p_new = p_old + ( provider_name, )
self.action_providers = p_new
- security.declarePrivate('listActions')
- def listActions(self, info):
- """
- List actions available from this tool
- """
- if info.isAnonymous:
- return None
- else:
- actions = []
- folder_url = info.folder_url
- content_url = info.content_url
- if folder_url is not None:
- actions.append(
- { 'name' : 'Folder contents'
- , 'url' : folder_url + '/folder_contents'
- , 'permissions' : ['List folder contents']
- , 'category' : 'folder'
- })
- return actions
-
security.declareProtected( CMFCorePermissions.ManagePortal
, 'deleteActionProvider'
)
@@ -162,16 +176,24 @@
break
else:
folder = aq_parent(aq_inner(folder))
-
- info = ActionInformation(self, folder, object)
-
+ ec = createExprContext(folder, portal, object)
+ ai_objs = []
actions = []
+ info = oai(self, folder, object)
# Include actions from specific tools.
for provider_name in self.listActionProviders():
provider = getattr(self, provider_name)
a = provider.listActions(info)
- if a:
- actions.extend(list(a))
+ if a and type(a[0]) is not type({}):
+ ai_objs.extend(list(a))
+ else:
+ for i in a:
+ actions.append(i)
+
+ if ai_objs:
+ for ai in ai_objs:
+ if ai.testCondition(ec):
+ actions.append(ai.getAction(ec))
# Include actions from object.
if object is not None:
@@ -181,7 +203,7 @@
if ti is not None:
defs = ti.getActions()
if defs:
- c_url = info.content_url
+ c_url = object.absolute_url()
for d in defs:
a = d['action']
if a:
@@ -197,7 +219,7 @@
'visible': d.get('visible', 1),
})
if hasattr(base, 'listActions'):
- a = object.listActions(info)
+ a = object.listActions()
if a:
actions.extend(list(a))
=== CMF/CMFCore/CatalogTool.py 1.21 => 1.22 ===
from AccessControl import ClassSecurityInfo
from utils import mergedLocalRoles
+from ActionProviderBase import ActionProviderBase
+from ActionInformation import ActionInformation
+from Expression import Expression
import os
import CMFCorePermissions
from Acquisition import aq_base
@@ -64,16 +67,19 @@
return list(allowed.keys())
-class CatalogTool (UniqueObject, ZCatalog):
+class CatalogTool (UniqueObject, ZCatalog, ActionProviderBase):
'''This is a ZCatalog that filters catalog queries.
'''
id = 'portal_catalog'
meta_type = 'CMF Catalog'
security = ClassSecurityInfo()
+ _actions = []
- manage_options = ( { 'label' : 'Overview', 'action' : 'manage_overview' }
+ manage_options = ( ZCatalog.manage_options +
+ ActionProviderBase.manage_options +
+ ({ 'label' : 'Overview', 'action' : 'manage_overview' }
,
- ) + ZCatalog.manage_options
+ ))
def __init__(self):
ZCatalog.__init__(self, self.getId())
@@ -82,6 +88,14 @@
#
# Subclass extension interface
#
+ security.declarePrivate('listActions')
+ def listActions(self, info=None):
+ """
+ Return a list of action information instances
+ provided via tool
+ """
+ return self._actions
+
security.declarePublic( 'enumerateIndexes' ) # Subclass can call
def enumerateIndexes( self ):
# Return a list of ( index_name, type ) pairs for the initial
=== CMF/CMFCore/MemberDataTool.py 1.12 => 1.13 ===
from CMFCorePermissions import ViewManagementScreens
import CMFCorePermissions
+from ActionProviderBase import ActionProviderBase
_marker = [] # Create a new marker object.
-class MemberDataTool (UniqueObject, SimpleItem, PropertyManager):
+class MemberDataTool (UniqueObject, SimpleItem, PropertyManager, ActionProviderBase):
'''This tool wraps user objects, making them act as Member objects.
'''
id = 'portal_memberdata'
meta_type = 'CMF Member Data Tool'
+ _actions = []
_v_temps = None
_properties = ()
security = ClassSecurityInfo()
- manage_options=( ( { 'label' : 'Overview'
+ manage_options=( ActionProviderBase.manage_options +
+ ({ 'label' : 'Overview'
, 'action' : 'manage_overview'
}
, { 'label' : 'Contents'
@@ -83,8 +86,11 @@
# 'portal_memberdata' interface methods
#
security.declarePrivate('listActions')
- def listActions(self, info):
- return None
+ def listActions(self, info=None):
+ """
+ Return actions provided via tool.
+ """
+ return self._actions
security.declarePrivate('getMemberDataContents')
def getMemberDataContents(self):
=== CMF/CMFCore/MembershipTool.py 1.16 => 1.17 ===
from CMFCorePermissions import ManagePortal
import CMFCorePermissions
+from ActionProviderBase import ActionProviderBase
import Acquisition
default_member_content = '''Default page for %s
@@ -37,22 +38,23 @@
in the Tool Box on the left.
'''
-class MembershipTool (UniqueObject, SimpleItem):
+class MembershipTool (UniqueObject, SimpleItem, ActionProviderBase):
# This tool accesses member data through an acl_users object.
# It can be replaced with something that accesses member data in
# a different way.
id = 'portal_membership'
meta_type = 'CMF Membership Tool'
-
+ _actions = []
security = ClassSecurityInfo()
- manage_options=( { 'label' : 'Overview'
- , 'action' : 'manage_overview'
- }
- , { 'label' : 'Configuration'
+ manage_options=( ({ 'label' : 'Configuration'
, 'action' : 'manage_mapRoles'
- }
- ) + SimpleItem.manage_options
+ },) +
+ ActionProviderBase.manage_options +
+ ( { 'label' : 'Overview'
+ , 'action' : 'manage_overview'
+ },
+ ) + SimpleItem.manage_options)
#
# ZMI methods
@@ -387,7 +389,7 @@
security.declarePrivate('listActions')
- def listActions(self, info):
+ def listActions(self):
return None
security.declarePublic('getHomeFolder')
=== CMF/CMFCore/PortalFolder.py 1.28 => 1.29 ===
, 'category' : 'folder'
}
- , { 'id' : 'syndication'
- , 'name' : 'Syndication'
- , 'action' : 'synPropertiesForm'
- , 'permissions' : (ManageProperties,)
- , 'category' : 'folder'
- }
)
}
,
=== CMF/CMFCore/RegistrationTool.py 1.7 => 1.8 ===
import CMFCorePermissions
import string, random
+from ActionProviderBase import ActionProviderBase
-class RegistrationTool (UniqueObject, SimpleItem):
+class RegistrationTool (UniqueObject, SimpleItem, ActionProviderBase):
# This tool creates and modifies users by making calls
# to portal_membership.
id = 'portal_registration'
@@ -37,9 +38,10 @@
security = ClassSecurityInfo()
- manage_options = ( { 'label' : 'Overview', 'action' : 'manage_overview' }
+ manage_options = (ActionProviderBase.manage_options +
+ ({ 'label' : 'Overview', 'action' : 'manage_overview' }
,
- ) + SimpleItem.manage_options
+ ) + SimpleItem.manage_options)
#
# ZMI methods
@@ -51,9 +53,6 @@
#
# 'portal_registration' interface methods
#
- security.declarePrivate('listActions')
- def listActions(self, info):
- return none
security.declarePublic('isRegistrationAllowed')
def isRegistrationAllowed(self, REQUEST):
=== CMF/CMFCore/SkinsTool.py 1.11 => 1.12 ===
from AccessControl import ClassSecurityInfo
from CMFCorePermissions import ManagePortal, AccessContentsInformation
+from ActionProviderBase import ActionProviderBase
+from ActionInformation import ActionInformation
+from Expression import Expression
from OFS.Image import Image
from OFS.DTMLMethod import DTMLMethod
@@ -53,20 +56,23 @@
'action':'manage_propertiesForm'}]
return tuple(rval)
-class SkinsTool(UniqueObject, SkinsContainer, PortalFolder):
+class SkinsTool(UniqueObject, SkinsContainer, PortalFolder, ActionProviderBase):
'''
This tool is used to supply skins to a portal.
'''
id = 'portal_skins'
meta_type = 'CMF Skins Tool'
+ _actions = []
cookie_persistence = 0
security = ClassSecurityInfo()
- manage_options = ( { 'label' : 'Overview', 'action' : 'manage_overview' }
+ manage_options = ( modifiedOptions() +
+ ({ 'label' : 'Overview', 'action' : 'manage_overview' }
,
- ) + modifiedOptions()
+ ) + ActionProviderBase.manage_options
+ )
def __init__(self):
self.selections = PersistentMapping()
@@ -89,6 +95,14 @@
request_varname = 'portal_skin'
allow_any = 0
selections = None
+
+ security.declarePrivate('listActions')
+ def listActions(self, info=None):
+ """
+ Return a list of actions information instances
+ provided by the tool.
+ """
+ return self._actions
security.declareProtected(ManagePortal, 'manage_propertiesForm')
manage_propertiesForm = DTMLFile('dtml/skinProps', globals())
=== CMF/CMFCore/TypesTool.py 1.26 => 1.27 ===
from Acquisition import aq_base
import Products, CMFCorePermissions
+from ActionProviderBase import ActionProviderBase
+from ActionInformation import ActionInformation
+from Expression import Expression
from CMFCorePermissions import View, ManagePortal, AccessContentsInformation
@@ -501,18 +504,21 @@
, ScriptableTypeInformation.meta_type
)
-class TypesTool( UniqueObject, OFS.Folder.Folder ):
+class TypesTool( UniqueObject, OFS.Folder.Folder, ActionProviderBase ):
"""
Provides a configurable registry of portal content types.
"""
id = 'portal_types'
meta_type = 'CMF Types Tool'
+ _actions = []
security = ClassSecurityInfo()
- manage_options = ( { 'label' : 'Overview', 'action' : 'manage_overview' }
+ manage_options = ( OFS.Folder.Folder.manage_options +
+ ActionProviderBase.manage_options +
+ ({ 'label' : 'Overview', 'action' : 'manage_overview' }
,
- ) + OFS.Folder.Folder.manage_options
+ ))
#
# ZMI methods
@@ -520,6 +526,14 @@
security.declareProtected( CMFCorePermissions.ManagePortal
, 'manage_overview' )
manage_overview = DTMLFile( 'explainTypesTool', _dtmldir )
+
+ security.declarePrivate('listActions')
+ def listActions(self, info=None):
+ """
+ Return a list of action information instances
+ for actions provided via tool
+ """
+ return self._actions
def all_meta_types(self):
all = TypesTool.inheritedAttribute('all_meta_types')(self)
=== CMF/CMFCore/UndoTool.py 1.4 => 1.5 ===
from string import split
from AccessControl import ClassSecurityInfo
-
+from Expression import Expression
+from ActionInformation import ActionInformation
+from ActionProviderBase import ActionProviderBase
from CMFCorePermissions import ManagePortal, UndoChanges, ListUndoableChanges
-class UndoTool (UniqueObject, SimpleItem):
+class UndoTool (UniqueObject, SimpleItem, ActionProviderBase):
id = 'portal_undo'
meta_type = 'CMF Undo Tool'
# This tool is used to undo changes.
+ _actions = [ActionInformation(id='undo'
+ , title='Undo'
+ , action=Expression(
+ text='string: ${portal_url}/undo_form')
+ , condition=Expression(
+ text='member')
+ , permissions=(ListUndoableChanges,)
+ , category='global'
+ , visible=1
+ )]
security = ClassSecurityInfo()
- manage_options = ( { 'label' : 'Overview', 'action' : 'manage_overview' }
+ manage_options = ( ActionProviderBase.manage_options +
+ SimpleItem.manage_options +
+ ({ 'label' : 'Overview', 'action' : 'manage_overview' }
,
- ) + SimpleItem.manage_options
-
+ ))
#
# ZMI methods
#
@@ -46,14 +59,11 @@
manage_overview = DTMLFile( 'explainUndoTool', _dtmldir )
security.declarePrivate('listActions')
- def listActions( self, info ):
- if info.isAnonymous:
- return []
- return [ { 'name': 'Undo'
- , 'url': 'undo_form'
- , 'permissions': [ ListUndoableChanges ]
- , 'category': 'global'
- } ]
+ def listActions(self, info=None):
+ """
+ List actions available through tool
+ """
+ return self._actions
#
# 'portal_undo' interface methods
=== CMF/CMFCore/WorkflowTool.py 1.19 => 1.20 ===
security = ClassSecurityInfo()
- manage_options = ( { 'label' : 'Overview', 'action' : 'manage_overview' }
- , { 'label' : 'Workflows'
+ manage_options = ( { 'label' : 'Workflows'
, 'action' : 'manage_selectWorkflows'
}
+ , { 'label' : 'Overview', 'action' : 'manage_overview' }
) + Folder.manage_options
#