ploneintranet.workspace package



ploneintranet.workspace.adapters module

class ploneintranet.workspace.adapters.GroupingStorage(context)[source]

Bases: object

Adapter that stores the sidebar’s groupings for quick lookup.

The groupings dict is arranged in the following way: OOBTree({

‘label’: {
‘Important’: set([uid, uid, uid]), ‘Frivolous’: set([uid, uid]),

} ‘author: {

‘max-mustermann’: set([uid]), ‘john-doe’: set([uid, uid]), ‘jane-doe’: set([uid]),

} ‘type’: {

‘foo’: set([uid]), ‘bar’: set([uid, uid, uid]), ‘baz’: set([uid]),

} ‘first_letter’: {

‘a’: set([uid]), ‘b’: set([uid, uid, uid]), ‘c’: set([uid]),


}) The top-level keys are the groupings.

For each grouping we store another dict.

Each key in this dict is a unique value for that grouping. These values are retrieved from the objects stored in the workspace.

For each key we have a list of uids. These are the uids of the objects that have that key as a field value (corresponding to the grouping).

Remember: each grouping is a field on an object, so each value of that grouping is a value of that field on an object inside the workspace.

We need to keep track of the uids, so that we know when to remove a grouping-value. When an object is modified, we don’t know if anything was removed (for example from the ‘Subject’ field, which corresponds to ‘label’ grouping).

So we have to check every time if that object’s uid is in any grouping values that that object doesn’t have anymore. In that way, we know to remove the uid from that grouping-value. If that grouping-value doesn’t have any uids anymore, we can remove it.

_add_grouping_values(grouping, values, obj)[source]

Add $uid to the list of uids stored under the grouping values (provided by $values) in the groupings datastructure.

If the list doesn’t exist yet, add it.

_remove_grouping_value(grouping, value)[source]

Remove entry $value under a given $grouping.

Can be used for bulk-changes to a grouping (e.g. changing a tag)

_remove_grouping_values(grouping, values, obj)[source]

Remove $uid from the list of uids stored under the grouping values (provided by $values) in the groupings datastructure.

If $uid is the only one in the list, then remove the list (and its key) entirely.

get_order_for(grouping, include_archived=False, alphabetical=False)[source]

Return the keys of the given grouping in order.


Return the last time this grouping storage was modified.


Remove obj’s grouping relevant information to its workspace.


Reset the order for all groupings to default, i.e. same order as the keys of the OOBTree

set_order_for(grouping, order)[source]

Set order for a given grouping


Update the groupings dict with the values stored on obj.

class ploneintranet.workspace.adapters.GroupingStorageValues(uids)[source]

Bases: Acquirer, OFS.owner.Owned, persistent.Persistent

A datastructure to store the UIDs of objects appearing under a specific grouping.

It conforms to the requirements imposed by OrderedBTreeFolderBase on its sub-objects (acquisition aware, ownable, persistent).

class ploneintranet.workspace.adapters.MetroMap(context)[source]

Bases: object


A data structure is stored as a TAL expression on a workflow which determines the sequence of workflow states/milestones used to render the metromap.

We need to evaluate the expression and returns the data structure.

It consists of a list of dicts each with the workflow state, the transition to the next milestone in the metromap, and the transition required to return to the milestone: [{

‘state’: ‘new’, ‘next_transition’: ‘finalise’, ‘reopen_transition’: ‘reset’
}, {
‘state’: ‘complete’, ‘next_transition’: ‘archive’, ‘reopen_transition’: ‘finalise’
}, {
‘state’: ‘archived’}



All Case Workspaces should have a placeful workflow. In order to render the metromap, this workflow needs to have a metromap_transitions variable which determines the order of the milestones (states) and the transitions between them.

Return the workflow required to render the metromap.


Return the data structure required for displaying the metromap, derived from the configuration in the metromap_transitions variable of the associated workflow.

An OrderedDict is used to provide details such as whether a milestone has already been finished, the transition required to close the current milestone, and the transition required to reopen the previous milestone.

In the ‘complete’ workflow state / milestone it returns the following: OrderedDict([(

‘new’, {
‘transition_title’: u’Transfer To Department’, ‘title’: u’New’, ‘finished’: True, # This milestone has been finished ‘is_current’: False, # Not the current milestone ‘reopen_transition’: ‘reset’, # For [Reopen milestone] ‘transition_id’: ‘transfer_to_department’

}), ( ‘complete’, {

‘transition_title’: u’Submit’, ‘title’: u’Content Complete’, ‘finished’: False, # This milestone isn’t finished yet ‘is_current’: True, # Current milestone: Show [Close milestone] ‘reopen_transition’: False, ‘transition_id’: ‘submit’

}), ( ‘archived’, {

‘transition_title’: ‘’, ‘title’: u’Archived’, ‘is_current’: False, ‘finished’: False, ‘reopen_transition’: False, ‘transition_id’: None



class ploneintranet.workspace.adapters.PloneIntranetWorkspace(context)[source]

Bases: collective.workspace.workspace.Workspace

A custom workspace behaviour, based on collective.workspace

Here we define our own available groups, and the roles they are given on the workspace.

add_to_team(userid, **kw)[source]

Add user/group to this workspace

We override this method from collective.workspace to add our additional participation policy groups, as detailed in available_groups above.

Also used to update an existing members’ groups.

available_groups = {u'Publishers': ('Contributor', 'SelfPublisher'), u'Consumers': (), u'Moderators': ('Reader', 'Contributor', 'Reviewer', 'Editor'), u'Producers': ('Contributor',), u'Admins': ('Contributor', 'Editor', 'Reviewer', 'Reader', 'TeamManager'), u'Guests': ('TeamGuest',), u'Members': ('TeamMember',)}

Lookup the collective.workspace usergroup corresponding to the given policy

Parameters:policy (str) – The value of the policy to lookup, defaults to the current policy

alias of PloneIntranetTeamMembership

update_participant_policy_groups(old_policy, new_policy)[source]

Move relevant members to a new default policy

We only move members who were previously part of the old policy. This allows for ‘exception’ users who have been promoted/demoted manually to retain their existing roles.

class ploneintranet.workspace.adapters.WorkspaceLocalRoleAdapter(context)[source]

Bases: borg.localrole.default_adapter.DefaultLocalRoleAdapter

If the user has the local role of Owner on the context and the acquired role of SelfPublisher; they should also be given Reviewer.


give an Owner who is also a ‘selfpublisher’, the reviewer role

ploneintranet.workspace.config module

exception ploneintranet.workspace.config.SecretWorkspaceNotAllowed[source]

Bases: exceptions.Exception module

class, old_policy, new_policy)[source]

Bases: zope.component.interfaces.ObjectEvent

Event class, which is fired once the participation policy of the workspace has changed


Bases: zope.component.interfaces.ObjectEvent


Bases: zope.component.interfaces.ObjectEvent

Event, which is fired once the roster of a workspace had changed

ploneintranet.workspace.indexers module

ploneintranet.workspace.interfaces module

interface ploneintranet.workspace.interfaces.IBaseWorkspaceFolder[source]

Bases: plone.supermodel.model.Schema, plone.namedfile.interfaces.IImageScaleTraversable

Interface for WorkspaceFolder

division = <zope.schema._bootstrapfields.TextLine object>


related_workspaces = <zope.schema._field.List object>


archival_date = <zope.schema._field.Datetime object>


email = <zope.schema._bootstrapfields.TextLine object>


calendar_visible = <zope.schema._bootstrapfields.Bool object>


event_global_default = <zope.schema._bootstrapfields.Bool object>


hero_image = <plone.namedfile.field.NamedBlobImage object>

Hero Image

default_grouping = <zope.schema._bootstrapfields.TextLine object>


interface ploneintranet.workspace.interfaces.IGroupingStoragable[source]

Bases: zope.interface.Interface

marker interface for things that can have a GroupingStorage

interface ploneintranet.workspace.interfaces.IGroupingStorage[source]

Bases: zope.interface.Interface


Update the groupings dict with the values stored on obj.


Reset the order for all groupings to default, i.e. same order as the keys of the OOBTree


Return groupings

set_order_for(grouping, order)

Set order for a given grouping


Remove obj’s grouping relevant information to its workspace.

get_order_for(grouping, include_archived=False, alphabetical=False)

Get order for a given grouping

interface ploneintranet.workspace.interfaces.IMail[source]


Marker interface for the ploneintranet.workspace.mail content type

interface ploneintranet.workspace.interfaces.IMetroMap[source]

Bases: zope.interface.Interface

Methods required to display a metromap


An ordered dict with the structure required for displaying tasks in the metromap and in the sidebar of a Case item. This is used to determine which states have been finished, and which transitions are currently available. OrderedDict([(

“new”, {
“is_current”: False, “transition_id”: “transfer_to_department”, “finished”: True,

}), ( “in_progress”, {

“is_current”: False, “transition_id”: “transfer_to_department”, “finished”: True,



interface ploneintranet.workspace.interfaces.IParticipationPolicyChangedEvent[source]

Bases: zope.interface.Interface

Event, which is fired once the participation policy of the workspace has changed

old_policy = <zope.interface.interface.Attribute object>

Policy we are moving away from

new_policy = <zope.interface.interface.Attribute object>

Policy we are moving to

interface ploneintranet.workspace.interfaces.IPloneintranetWorkspaceLayer[source]

Bases: zope.interface.Interface

Zope 3 browser layer which is active regardless of themeswitching

interface ploneintranet.workspace.interfaces.IThemedWorkspaceLayer[source]

Bases: ploneintranet.workspace.interfaces.IPloneintranetWorkspaceLayer, ploneintranet.layout.interfaces.INoBarcelonetaLayer

Zope 3 browser layer which is not present in Barceloneta fallback

interface ploneintranet.workspace.interfaces.ITrashable[source]

Bases: zope.interface.Interface

Marker interface for objects that can be trashed

interface ploneintranet.workspace.interfaces.ITrashed[source]

Bases: ploneintranet.workspace.interfaces.ITrashable

Marker interface for objects that are trashed

interface ploneintranet.workspace.interfaces.IWorkspaceAppContentLayer[source]

Bases: ploneintranet.layout.interfaces.IPloneintranetContentLayer, ploneintranet.layout.interfaces.IAppLayer

Marker interface for content within a workspace app.


Set the request’s publication object


Traverse from the given object to the published object

The published object is returned.

The following hook methods on the publication will be called:

  • callTraversalHooks is called before each step and after the last step.
  • traverseName to actually do a single traversal

Return the request traversal stack

This is a sequence of steps to traverse in reverse order. They will be traversed from last to first.


Query for an attribute description

locale = <zope.interface.interface.Attribute object>

Return the locale object associated with this request.

debug = <zope.interface.interface.Attribute object>

Debug flags (see IDebugFlags).

interaction = <zope.interface.interface.Attribute object>

The interaction


Change the traversal stack.

See getTraversalStack.


Release resources held by the request.


Hold a reference to an object until the request is closed.

The object should be an IHeld. If it is an IHeld, its release method will be called when it is released.

response = <zope.interface.interface.Attribute object>

The request’s response object

Return an IPublisherResponse for the request.


Setup the locale object based on languages returned by IUserPreferredLanguages adapter.

principal = <zope.interface.interface.Attribute object>

The authenticated principal


Return a retry request

Return a request suitable for repeating the publication attempt.

publication = <zope.interface.interface.Attribute object>

The request’s publication object

The publication object, an IRequestPublication provides application-specific functionality hooks.


Return the items of the mapping object.


Add additional traversal steps to be taken after all other traversal

This is used to handle HTTP request methods (except for GET and POST in the case of browser requests) and XML-RPC methods.


Do any input processing that needs to be done before traversing

This is done after construction to allow the publisher to handle errors that arise.

method = <zope.interface.interface.Attribute object>

Request method, normalized to upper case

environment = <zope.interface.interface.Attribute object>

Request environment data

This is a read-only mapping from variable name to value.


Return the keys of the mapping object.


Return the values of the mapping object.

bodyStream = <zope.interface.interface.Attribute object>

The stream that provides the data of the request.

The data returned by the stream will not include any possible header information, which should have been stripped by the server (or previous layer) before.

Also, the body stream might already be read and not return any data. This is commonly done when retrieving the data for the body attribute.

If you access this stream directly to retrieve data, it will not be possible by other parts of the framework to access the data of the request via the body attribute.


Return the positional arguments given to the request.


Set the principal attribute.

It should be IPrincipal wrapped in its AuthenticationService’s context.


Check whether the request supports retry

Return a boolean value indicating whether the request can be retried.

annotations = <zope.interface.interface.Attribute object>

Stores arbitrary application data under package-unique keys.

By “package-unique keys”, we mean keys that are are unique by virtue of including the dotted name of a package as a prefex. A package name is used to limit the authority for picking names for a package to the people using that package.

For example, when implementing annotations for hypothetical request-persistent adapters in a hypothetical zope.persistentadapter package, the key would be (or at least begin with) the following:

interface ploneintranet.workspace.interfaces.IWorkspaceAppFormLayer[source]

Bases: ploneintranet.layout.interfaces.IPloneintranetFormLayer, ploneintranet.layout.interfaces.IAppLayer

Marker interface for forms within a workspace app.

interface ploneintranet.workspace.interfaces.IWorkspaceCreatedFromTemplateEvent[source]

Bases: zope.interface.Interface

A workspace has been created by copying a template. This event allows us to disable the auditlog while the other events are fired and then create only one entry via this event. Otherwise all items contained in the template trigger audit entries when copied.

interface ploneintranet.workspace.interfaces.IWorkspaceFolder[source]

Bases: ploneintranet.workspace.interfaces.IBaseWorkspaceFolder

A workspace folder can be a division, while other objects inheriting from IBaseWorkspaceFolder cannot, e.g. cases

division = <zope.schema._bootstrapfields.TextLine object>


related_workspaces = <zope.schema._field.List object>


is_division = <zope.schema._bootstrapfields.Bool object>


Divisions represent sections of the overall organisation and appear as groupings on the workspace overview.

archival_date = <zope.schema._field.Datetime object>


email = <zope.schema._bootstrapfields.TextLine object>


calendar_visible = <zope.schema._bootstrapfields.Bool object>


event_global_default = <zope.schema._bootstrapfields.Bool object>


hero_image = <plone.namedfile.field.NamedBlobImage object>

Hero Image

default_grouping = <zope.schema._bootstrapfields.TextLine object>


interface ploneintranet.workspace.interfaces.IWorkspaceRosterChangedEvent[source]

Bases: zope.interface.Interface

Event, which is fired once the roster of a workspace had changed

interface ploneintranet.workspace.interfaces.IWorkspaceState[source]

Bases: zope.interface.Interface

A view that gives access to the containing workspace


The state of the workspace


The workspace

ploneintranet.workspace.policies module

Defines the policies that can be applied to a workspace

ploneintranet.workspace.setuphandlers module

  • adds the global “workspaces” container
  • adds the global “templates” case templates container (actual case template is provided by ploneintranet.suite)
  • sets an acl user group to hold all intranet users
  • setup the dynamic groups plugin
  • makes sure the membrane groups plugin is ordered before the recursive groups plugin
  • sets the addable types for the ploneintranet policy

ploneintranet.workspace.subscribers module

ploneintranet.workspace.testing module

ploneintranet.workspace.utils module

class ploneintranet.workspace.utils.OpenEndedGraph(nodes, edges)[source]

Bases: object


Return all the descendants of a node

get_meaningful_children(start_node, edges=None)[source]

Given a start node, return all the edges endpoints that lead to (at least) another node.

We work on copy of the edges to avoid circular relations: once an edge is evaluated it is discarded


helper function to get annotation storage on the portal

Parameters:clear – If true is passed in, annotations will be cleared
Returns:portal annotations
Return type:IAnnotations
ploneintranet.workspace.utils.map_content_type(mimetype, portal_type='')[source]

takes a mimetype and returns a content type string as used in the prototype


Return containing workspace Returns None if not found.


Return containing workspace Returns None if not found.


This is necessary in case you have a cache on your acl_users folder.

This method purges the configured cache on the acl_users folder and reinitialises the security manager for the current user.

This is necessary as example when we are creating a workspace and right afterwards transition it into the private state. The transition is guarded by the TeamManager role which the current user just got when the workspace was created. This is however not yet reflected in the cached user object. This would not be an issue in the next upcoming request as the security context will be rebuilt then, but in the current request, this is a problem.

ploneintranet.workspace.utils.send_email(recipient, subject, message, sender='')[source]

helper function to send an email with the sender preset

ploneintranet.workspace.workspacecontainer module

interface ploneintranet.workspace.workspacecontainer.IWorkspaceContainer[source]

Bases: plone.supermodel.model.Schema, plone.namedfile.interfaces.IImageScaleTraversable, ploneintranet.layout.interfaces.IAppContainer

Marker interface for WorkspaceContainer

app_layers = <zope.interface.interface.Attribute object>

A list of IAppLayer to be activated on traversal

app_name = <zope.interface.interface.Attribute object>

Name of the app. Will be set as app-{name} on body.

class ploneintranet.workspace.workspacecontainer.WorkspaceContainer(*args, **kwargs)[source]

Bases:, plone.dexterity.content.Container

A folder to contain WorkspaceFolders.

Implements IAppContainer to enable workspace-specific content view registrations.

app_layers = (<InterfaceClass ploneintranet.workspace.interfaces.IWorkspaceAppContentLayer>, <InterfaceClass ploneintranet.workspace.interfaces.IWorkspaceAppFormLayer>)
app_name = 'workspace'

ploneintranet.workspace.workspacefolder module

Module contents