Sharing is caring! In this use-case I will describe all actions done to get my workflow working.
In my case there are two roles: processowner and author. The processowner has the rights to iterate and checkout a bookpage. He or she then is able to share this item to someone who will get the author role. The author has the rights to set the workflow to 'written' when he is done. The processowner will checkin the page and it will return to the 'concept' state again.
There is a contenttype called bookpage, which is just a normal document including some additional fields.
The workflow
Below is a schema of the setup I need to create for my bookpage contenttype.
Iterate
First thing to do is to setup the iterate part. We need to add our 'bookpage' to versionable types. This can be done by editing the setuphandler.py and adding the following code.
from Products.CMFEditions.setuphandlers import DEFAULT_POLICIES
TYPES_TO_VERSION = ['bookpage']
def installVersionedTypes(context):
if isNotClientProfile(context):
return
site = context.getSite()
logger.info('adding default versionable_types to website...')
portal_repository = getToolByName(site, 'portal_repository')
versionable_types = list(portal_repository.getVersionableContentTypes())
for type_id in TYPES_TO_VERSION:
if type_id not in versionable_types:
versionable_types.append(type_id)
for policy_id in DEFAULT_POLICIES:
portal_repository.addPolicyForContentType(type_id, policy_id)
portal_repository.setVersionableContentTypes(versionable_types)
def importVarious(context):
"""Miscellanous steps import handle"""
portal = context.getSite()
installVersionedTypes(portal)
We also need to tell diff_tool to add our contenttype so history and iterate will work.
diff_tool.xml
<?xml version="1.0"?>
<object>
<difftypes>
<type portal_type="bookpage">
<field name="any" difftype="Compound Diff for AT types"/>
</type>
</difftypes>
</object>
Workflow
One of the easiest ways to create a new workflow for my bookpage is to copy an existing workflow using the ZMI and rename it to whatever you want it to be. In our case we call it 'book_workflow'.
workflows.xml
<?xml version="1.0"?>
<object name="portal_workflow" meta_type="Plone Workflow Tool">
<property
name="title">Contains workflow definitions for your portal</property>
<object name="book_workflow" meta_type="Workflow"/>
<bindings>
<type type_id="Book">
<bound-workflow workflow_id="book_workflow"/>
</type>
</bindings>
</object>
definition.xml
<?xml version="1.0"?>
<dc-workflow workflow_id="book_workflow"
title="Book Workflow"
description=""
state_variable="review_state"
initial_state="concept">
<permission>Access contents information</permission>
<permission>List folder contents</permission>
<permission>Modify portal content</permission>
<permission>View</permission>
<state state_id="concept" title="Concept">
<exit-transition transition_id="provide_written"/>
<exit-transition transition_id="provide_for_publication"/>
<permission-map name="Access contents information"
acquired="False">
<permission-role>Contributor</permission-role>
<permission-role>Editor</permission-role>
<permission-role>Manager</permission-role>
<permission-role>Owner</permission-role>
<permission-role>Author</permission-role>
<permission-role>Processowner</permission-role>
</permission-map>
< ......... more states here ....... >
<transition transition_id="provide_for_publication"
title="Provide for publication"
new_state="readyforpublication" trigger="USER"
before_script="" after_script="">
<action url="%(content_url)s/content_status_modify?workflow_action=provide_for_publication"
category="workflow">Provide for publication</action>
<guard>
<guard-permission>Modify portal content</guard-permission>
<guard-role>Processowner</guard-role>
<guard-role>Manager</guard-role>
</guard>
</transition>
< ......... more transitions here ....... >
</dc-workflow>
Restrict transition on multiple roles so only the Manager and Processowner can do 'Provide fo publication'
<guard-role>Processowner</guard-role>
<guard-role>Manager</guard-role>
We do the same thing for Author and Manager on the Transition 'Provide written' so only the author can set the state 'written'.
Note: in the ZMI we can do the same thing. We need to use a semicolon as the seperaror.
|
Permissions and Sharing
The processowners needs the rights to share the author role to someone, so we need to setup a permission 'Delegate Author Role'.
permissions.py
from Products.CMFCore.permissions import setDefaultRoles
from AccessControl import ModuleSecurityInfo
security = ModuleSecurityInfo("client.contenttypes.permissions")
security.declarePublic("DelegateAuthorRole")
DelegateAuthorRole = "Sharing page: Delegate Author role"
setDefaultRoles(DelegateAuthorRole, ('Manager',))
sharing.py
from zope.interface import implements
from plone.app.workflow.interfaces import ISharingPageRole
from client.contenttypes import permissions
class AuthorRole(object):
implements(ISharingPageRole)
title = _(u"title_author", default=u"Author")
required_permission = permissions.DelegateAuthorRole
permissions.zcml
<configure xmlns="http://namespaces.zope.org/zope"
i18n_domain="client.contenttypes">
<!-- Our custom permissions -->
<permission
id="client.contenttypes.DelegateAuthorRole"
title="Sharing page: Delegate Author role"
/>
</configure>
Tell include in configure.zcml we have done above.
configure.zcml
<include file="permissions.zcml" />
<utility name="Author" factory=".sharing.AuthorRole"/>
Rolemap
Setup the security settings for Processowner. He needs to get 'Delegate Author role' and 'Delegate roles' for showing the sharing tab. We can also set the rights for the author role using rolemap.xml.
rolemap.xml
<?xml version="1.0"?>
<rolemap>
<roles>
<role name="Author"/>
<role name="Processowner"/>
</roles>
<permission name="Sharing page: Delegate Author role"
acquire="True">
<role name="Manager"/>
<role name="Processowner"/>
</permission>
<permission name="Sharing page: Delegate roles"
acquire="True">
<role name="Processowner"/>
</permission>
</rolemap>
Exportsettings
Best thing to do is export you workflow and security settings using the ZMI. Go to the portal_setup tool where you can export all kinds of XML.
Export 'Workflow Tool', 'Placeful Workflow policies' and 'Role / Permission Map' and put them in your contenttype profiles directory.
Directory stucture from client.contenttypes:
![]() |
Result
We are now able to share the role Author at the sharing page in Plone.
Dutch version |
The author has the rights to edit the page and change the workflow, this is done by setting the rights at the rolemap.xml