Generic Setup

« Return to page index

Plone Developer Manual is a comprehensive guide to Plone programming.

1. What is GenericSetup?

A brief overview of what GenericSetup is

GenericSetup is a product that allows developers to import and export site configuration. This product was created to counteract Seaver's Law, which states the following: "Persistence means always having to say you're sorry". This means that any time you configure your Plone site purely through the Plone interface or ZMI you run the risk of losing your configuration. Since your configuration was only persisted into the ZODB, if you lose your data, you also lose your configuration.

This is where GenericSetup comes in to save the day. You can still make all your configuration changes in the Plone site or through the ZMI. Then when you are ready you can export these settings using the portal_setup tool.

GenericSetup was introduced in Plone 2.5 to help replace the use of customization policies and the quick installer. The old methods relied on the user to write Python code to set up their product or site.  When the API of the tools and objects changed the install and uninstall methods would also have to be changed. GenericSetup gives us a way to deal with the settings that we want to import and export and not have to worry about the API changing over time.

2. GenericSetup Profiles

How to setup a GenericSetup profile

2.1. What is a profile?

Information on what a GenericSetup profile is for

A GenericSetup profile is a preset configuration of a site, defined on the filesystem. This configuration can consist on a broad variety of settings, including roles and permissions mappings, skin layers order, site properties...

2.2. Profile types

Information about the different types of GenericSetup profiles

GenericSetup has two kinds of profiles that you can create. A base profile is a profile that defines the basis for the site configuration.  In Plone the base profile is the "plone" profile from the CMFPlone product. A base profile is not typically something that product developers needs to deal with.  There can only be one base profile in use, when you create a new Plone site the base profile is applied for you.  The base profile will setup a default set of import and export steps along with a default configuration for each.

The second type of profile is an extension profile. An extension profile is what allows us to build on top of the base profile. When you create a new product, theme or policy package you will register extension profiles to build on top of the existing configuration. Extension profiles also allow you to define new import and export steps that other extension profiles can use.

2.3. Registering a profile

Learn how to register a profile

GenericSetup profiles are registered via ZCML. The registration is typically done in the configure.zcml of your package. Let's register a default profile for our example my.package

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
    i18n_domain="my.package">

  <genericsetup:registerProfile
      name="default"
      title="My Package"
      directory="profiles/default"
      description="Default profile for My Package"
      provides="Products.GenericSetup.interfaces.EXTENSION"
      />

</configure>

This is what we would see in the configure.zcml of my.package.  Let's examine what each of the attributes of the registerProfile directive mean.

name
The name is how GenericSetup will identify your profile.  The full profile id is "profile-<package_name>:<profile_name>", in our case profile-my.package:default
title
The title of the profile will show up in the portal_setup tool when you select what profile you want to import. The title may also be used in the portal_quickinstaller if it picks up the profile as the install profile for your package.
directory
The directory attribute is the relative path to the folder containing the profile information.  The directory name is conventionally the same as the profile name.
description
The description gives a brief summary of what the profile is used for.
provides
The provides attribute tells GenericSetup what kind of profile you are registering. For almost all cases you will be registering an extension profile to extend Plone's base profile.

3. Using GenericSetup Efficiently

Tips about getting the most out of GenericSetup

Once you have your GenericSetup profile set up you'll need to start adding import files into it. It is common for people to think that they have to write all the XML by hand. This should almost never be the case.

Change and export

The easiest way to to make changes with GenericSetup is to make the changes in your site and then export the corresponding step. Let's start with a very basic example, changing the MailHost settings so that we can send out mail.

Go to the ZMI (http://yourplonesite:8080/manage) and find the MailHost object in the Plone site root. Enter the configuration data for your mail provider. Now go to portal_setup and click on the Export tab. Click the checkbox next to the MailHost import step and then on the Export selected steps button.

A targz bundle with the XML declarations of this exported import step will be generated and downloaded. Note you can select as many import steps as necessary or even export all steps directly so you have a complete snapshot of the configuration of the your site.

Trimming down the export

When you export settings from from GenericSetup, you will get more than what you changed. It's a very good idea to trim down the export file to only have the specific items that you changed. If you don't trim down the file then you will inadvertently override a change that is made in another profile.

A common example is the propertiestool.xml export. This exports the properties in the portal_properties tool. Let's say you have modified the default_language property in portal_properties/site_properties and you want to save it for your policy product. If you go to portal_setup and export the Plone Properties, the generated propertiestool.xml will more than 100 lines long.

Since you have only modified a property and you're using a extension profile, you only have to keep the configuration data for this property.

<?xml version="1.0"?>
<object name="portal_properties" meta_type="Plone Properties Tool">
 <object name="site_properties" meta_type="Plone Property Sheet">
  <property name="default_language" type="string">en</property>
 </object>
</object>

Play well with others

When writing Plone add-ons you need to be aware of how your profile is going to interact with other add-ons and custom packages.

By default existing settings are purged before applying settings from base profiles. Extension profiles are applied in update mode.

However, you can use the purge="True" and purge="False" directives to override the default behavior. If True the existing settings of the current object are always purged, if False they are not purged.

For example, the declarations in the propertiestool.xml in an extension profile:

<?xml version="1.0"?>
<object name="portal_properties">
    <object name="navtree_properties">
        <property name="metaTypesNotToList" type="lines" purge="False">
           <element value="Promotion"/>
        </property>
    </object>
</object>

will append the Promotion type to the list of content types not to list in the navigation trees, leaving the rest of them intact, whereas, in the same extension profile

<?xml version="1.0"?>
<object name="portal_properties">
    <object name="navtree_properties">
        <property name="metaTypesNotToList" type="lines" purge="True">
           <element value="Promotion"/>
        </property>
    </object>
</object>

would remove all previous elements from the mentioned list and let Promotion alone.

User editable settings

Another thing to take into consideration is the fact that some of the properties or settings that you are importing can be changed by the end user. The most common of these properties would be the site title. The end user can easily change this setting by going to the Plone control panel.

Be careful not to place a setting like this in a profile that runs when your product is re-installed. This could lead to the end users' changes being wiped out each time. You can place these settings in another profile that can be run on the initial creation of the site.

4. GenericSetup Reference

Information about how each import/export step handles the data given to it

4.1. Actions

Information about action import and export

GenericSetup can export the actions that are set up in each of the action providers. When you export the actions step then you will be given an actions.xml file. Here is an excerpt from the actions.xml file.

<?xml version="1.0"?>
<object name="portal_actions" meta_type="Plone Actions Tool"
   xmlns:i18n="http://xml.zope.org/namespaces/i18n">

 <action-provider name="portal_workflow"/>
 <action-provider name="portal_types"/>
 <action-provider name="portal_actions"/>

 <object name="document_actions" meta_type="CMF Action Category">

  <object name="print" meta_type="CMF Action" i18n:domain="plone">
   <property name="title" i18n:translate="">Print this</property>
   <property name="description" i18n:translate=""></property>
   <property name="url_expr">string:javascript:this.print();</property>
   <property name="icon_expr">string:$portal_url/print_icon.png</property>
   <property name="available_expr"></property>
   <property name="permissions">
    <element value="View"/>
   </property>
   <property name="visible">True</property>
  </object>

  <!-- more actions here -->

 </object>
</object>

Here we can see that there are three different things being defined here. First is the list of action providers as defined in the portal_actions tool. Each action-provider element provides the name of the tool or object that provides the actions. In the following example the types tool is being set up.

<action-provider name="portal_types"/>

The next element that you see is the document_actions. This is an action category in the portal_actions tool. Each action category is a folder of actions. You can see that the category is defined as follows.

<object name="document_actions" meta_type="CMF Action Category">
  <!-- contained actions here -->
</object>

Action Objects

Inside the action category are the actions. In our example above we were looking at the print action. Here is the action.

  <object name="print" meta_type="CMF Action" i18n:domain="plone">
   <property name="title" i18n:translate="">Print this</property>
   <property name="description" i18n:translate=""></property>
   <property name="url_expr">string:javascript:this.print();</property>
   <property name="icon_expr">string:$portal_url/print_icon.png</property>
   <property name="available_expr"></property>
   <property name="permissions">
    <element value="View"/>
   </property>
   <property name="visible">True</property>
  </object>

The object element has a name of print, this is the id of the action. We know that this object is an action because its meta_type is CMF Action. Inside of the action object we can see the properties for that action. These correspond to the form that we see in the ZMI.

Each property consists of the name and the value inside the element. Let's say we wanted to add a description to the print action. We would modify the description property as follows.

<property name="description">Print the current page</property>

Permissions

The permissions property accepts multiple elements. If you want multiple permissions you could add multiple elements to the permissions property as follows.

<property name="permissions">
 <element name="Modify portal content"/>
 <element name="Manage portal"/>
</property>

The name of each element is the name of the permission as seen on the security tab or on the action form in the ZMI. Of course, the easiest way to modify these settings is to change them in the ZMI and then export. This way there is no guess work involved.

Visible

The visible property is a boolean. This means it has a slightly different syntax. If you want the action to show up then you would set it to True.

<property name="visible">True</property>

And of course, if you want to hide it then you would set the value to False.

<property name="visible">False</property>

Please note that hiding an action affects only the UI and won't disable it. It will still be accessible using the associated URL.

Removing Action Objects

You can remove actions and action categories via the actions.xml. First let's see how to remove a particular action. In the following example we will remove the print action.

<object name="print" remove="True"/>

Since we are removing the action, all we need to do is define the name and add the remove attribute. Here is what our actions.xml would look like if we were to remove that action.

<?xml version="1.0"?>
<object name="portal_actions">
 <object name="document_actions">
  <object name="print" remove="True"/>
 </object>
</object>

We could do the same for the whole category with the following.

<?xml version="1.0"?>
<object name="portal_actions">
 <object name="document_actions" remove="True"/>
</object>

4.2. Catalog

Information about the import and export of catalog indexes, metadata and settings.

The Catalog Tool is the tool that Plone uses for indexing and searching content. Check the Indexing and Searching section of the Developer Manual for more information about how the Catalog Tool works.
Imagine you've created an 'Apartment' content-type using Archetypes with a field called 'address'. To index the address of each apartment so to be able to search by this field, create a catalog_tool.xml file in your extension profile with the following content:

<?xml version="1.0"?>
<object name="portal_catalog" meta_type="Plone Catalog Tool">
  <index name="address" meta_type="FieldIndex">
    <indexed_attr value="getAddress" />
  </index>
  <column value="a_field" />
</object>

The first line after the xml declaration specifies the type of object GenericSetup is dealing with: the Plone Catalog Tool, with id portal_catalog.
The 'index' node will create a new index of the type 'meta_type' with the name specified. You can find a list of the available meta-types, as well as the differences between them in the Searching and Categorizing Content section of The Zope Book.
The 'indexed_attr' node specifies the name of the attribute or method that will be called in each content object to index its values. This is useful, for example, if you want to create an index named 'Address' from the values returned by the getAddress() method.
The 'column' node will register a new column in the metadata table of the Plone Catalog Tool, so to include it in the returned brains.
Some index types has different properties which can be set up using 'property' and 'extra' nodes. For example, the default 'modified' index in Plone is registered with the following code:

<index name="modified" meta_type="DateIndex">
 <property name="index_naive_time_as_local">True</property>
</index>

Here, the property specifies that the time stored will be the local time instead of the UTC time.
Another example is the default 'SearchableText' field:

<index name="SearchableText" meta_type="ZCTextIndex">
  <indexed_attr value="SearchableText"/>
  <extra name="index_type" value="Okapi BM25 Rank"/>
  <extra name="lexicon_id" value="plone_lexicon"/>
</index>

 Here, the index_type attribute specifies the ranking strategy for the index. For searches in text indexes, the results are returned in order of relevancy - the algorithm used to order the results is the ranking strategy. The available ranking stragegies are Okapi BM25 Rank and Cosine Measure. See The sorting subsection of the Searching and Categorizing Content section of The Zope Book for details on this.

The lexicon_id specifies the lexicon used for the text index. Lexicons process and store the words from the text and help in processing queries, for example, turning the text into lowercase or removing very common words in a language like "the" or "and". See The Lexicons subsection of the Searching and Categorizing Content section of The Zope Book for details on this.

4.3. Control Panel

Information about the import and export of the Control Panel settings

The controlpanel.xml file keeps the information about the different configuration dialogs available for the different users, including members and site managers.

An excerpt of the the Plone controlpanel.xml file showing the general syntax follows:

<?xml version="1.0"?>
<object name="portal_controlpanel" meta_type="Plone Control Panel Tool"
    xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="plone">
 ...
 <configlet title="Change Password" action_id="MemberPassword" appId="Plone"
    category="Member" condition_expr="python:member.canPasswordSet()"
    icon_expr="string:$portal_url/lock_icon.png"
    url_expr="string:${portal_url}/password_form" visible="True"
    i18n:attributes="title">
  <permission>Set own password</permission>
 </configlet>
 ...
</object>

Each configuration dialog is called a configlet. The different attributes available are:

title
The human readable text to be shown in the Plone interface.
action_id
A unique identifier for the configlet.
appId
An application identifier for the configlet. This application id can be shared by more than one configlet and can be useful, for example, to remove all configlets related to a certain application in one go.
category
A category id to specify the area of the Plone interface where the configlet should be shown. Using the Plone category will cause it to be shown in the main site setup configuration panel, while the Member category will make it show in the list of configuration options for the account of the user logged in.
condition_expr
A TALES expression to control if the configlet is available or not. In the example above, the Change Password configlet will only be available if the current user can actually change her password.
icon_expr
 The URL of the icon for the configlet in TALES, to be shown in the Plone interface where applicable. Leave empty if there isn't any icon associated.
url_expr
The URL of the configlet dialog, i.e. the view or form the user should use to perform the configuration changes.
visible
Controls if the configlet will be shown or not. Useful if you want to disable a configlet temporarily for any reason.

The <permission> nodes inside the <configlet> one specify the neccessary permissions to use the configlet.

4.4. Component Registry

Information about component registration with GenericSetup.

To register an (Zope3-like) utility local to your Plone site you can use a componentregistry.xml file in your profile.
Imagine you write an utility that connects to an external Internet video streaming service like YouTube, sending and receiving data using the API provided by them. Since you can only have a single simultaneus connection, you need an singleton utility to look up and use. Each site (you have more than one in the same instance) has its own login account, so you need to register the utility locally instead of globally.
Let's say that your utility provides the yourcompany.video.interfaces.IExternalVideo interface, and it's implemented in the yourcompany.video.ExternalVideo.ExternalVideo class. Write the following code into your componentregistry.xml file:

<?xml version="1.0"?>
<componentregistry>
  <utilities>
    <utility
      interface="yourcompany.video.interfaces.IExternalVideo"
      factory="yourcompany.video.ExternalVideo.ExternalVideo"
    />
  </utilities>
</componentregistry>

The utility will be registered upon the installation of the product.

4.5. Factory Tool

Information about the Factory tool settings import and export.

Use the factorytool.xml import steps to include new types into the Plone Factory Tool  when creating new Archetypes content-types. This is needed because Archetypes needs the content to be already created before validating it. In order to avoid broken objects in the site, they're first created in a place called portal factory and moved to the desired place later after they've been validated.
Imagine you've created the Cat content-type and want to register a factory for it. Just create a factorytool.xml file for your extension profile with the following contents:

<?xml version="1.0"?>
<object name="portal_factory" meta_type="Plone Factory Tool">
  <factorytypes>
    <type portal_type="Cat"/>
  </factorytypes>
</object>

Check the Archetypes Developer Manual for more info about how to create content-types.

4.6. MailHost

Information about the import and export of MailHost settings.

Use this step to configure the MailHost tool to match your SMTP server settings. This example should speak for himself:

<?xml version="1.0"?>
<object name="MailHost" meta_type="Secure Mail Host" 
    smtp_host="smtp.mydomain.tld"
    smtp_port="25" 
    smtp_pwd="secret123" smtp_uid="myusername@mydomain.tld"/>

 

4.7. Metadata

Info about GenericSetup metadata

GenericSetup profiles can define a metadata.xml file with some metadata about that particular profile. The contents are straight forward and don't need much explanation. Here is an example.

<?xml version="1.0"?>
<metadata>
  <description>This is the profile description</description>
  <version>1</version>
  <dependencies>
    <dependency>profile-my.package:default</dependency>
    <dependency>profile-collective.foo:default</dependency>
  </dependencies>
</metadata>

There are three pieces to the metadata.xml file. We will go into more detail for each piece here.

Description

First there is the description element. This is where you can give a brief explanation of the profile.

<description>My package's default installation profile</description>

Version

Next is the version element. This tells GenericSetup what the version of the profile is. The version number will be used to run upgrade steps. Upgrade steps only run between the given version numbers. The version will be a whole number that is incremented when the profile has been changed. Here is an example.

<version>42</version>

In Plone 3.1 the practice of using the GenericSetup profile version as a fall back for the QuickInstaller version was deprecated. The QuickInstaller version will be taken from your product's version instead.

Dependencies

You can define profile dependencies via the metadata.xml file. When your profile is run, the dependencies that are listed will be run first. You can define as many dependencies as you like. If you wanted your profile to depend on the fictitious my.package profile named default then you would have the following in your metadata.xml.

<dependencies>
  <dependency>profile-my.package:default</dependency>
</dependencies>

The format for the profile entries are profile-<package_name>:<profile_name>. Here is an example of what an egg in the Products namespace would look like.

<dependencies>
  <dependency>profile-Products.MyPloneProduct:default</dependency>
</dependencies>

See the profile reference page for more details about GenericSetup profiles.

4.8. Portlets

Information about the import and export of portlets

The portlets.xml file lets you register portlets and portlet managers. For more info about the portlets infrastructure, check the Portlets chapter of the Developer Manual.

Let's see an excerpt of the Plone portlets.xml file:

<?xml version="1.0"?>
<portlets
    xmlns:i18n="http://xml.zope.org/namespaces/i18n"
    i18n:domain="plone">
 ...
 <portletmanager 
   name="plone.leftcolumn" 
   type="plone.app.portlets.interfaces.ILeftColumn"
   />
 ...
 <portlet 
   addview="portlets.News"
   title="News"
   description="A portlet which can render a listing of recent news"
   i18n:attributes="title;
                    description"
   >
   <for interface="plone.app.portlets.interfaces.IColumn" /> 
   <for interface="plone.app.portlets.interfaces.IDashboard" />  
 </portlet>
</portlets>

The <portletmanager /> node registers a portlet manager. The available attributes are:

name
The name of the utility providing the IPortletManager interface which will be instantiated.
type
A marker interface that can be used to install particular portlets only for particular types of portlet managers later.

The <portlet> node registers a portlet. The available attributes are:

addview
Somewhat confusing, should match the portlet name as registered in ZCML.
title and description
Human friendly text to be shown in the Plone user interface.

The <for /> nodes inside the <portlet> one specify the interfaces of the type of portlet managers that this portlet is suitable for.

The

<portlet addview="portlets.BBB" 

         title="Foo" 

         description="Foo" 

         for="plone.app.portlets.interfaces.IColumn" />

syntax to specify the allowed portlet manager interfaces was deprecated in Plone 3.1 and won't work in Plone 4.

Assigning portlets

You can assign portlets to certain parts of the site upon product installation using Generic Setup too. For example:

 <assignment
     manager="plone.rightcolumn"
     category="context"
     key="/"
     type="portlets.News"
     name="news"
     visible="1"
     />

The visible attribute was introduced in Plone 4. If not present or equal to "1", the portlet will be shown. If it's equal to "0", it will be hidden.

You can use the insert-after and insert-before attributes matching an existing assignment or all them with "*". For example:

 <assignment
     insert-before="events"
     manager="plone.rightcolumn"
     category="context"
     key="/"
     type="portlets.News"
     name="news"
     />

will insert the news portlet just before the events one.

You can also remove a certain assignment:

 <assignment
     remove="True"
     manager="plone.rightcolumn"
     category="context"
     key="/"
     type="portlets.News"
     name="news"
     />

Or remove (purge)all the assignments from a certain manager:

 <assignment
     purge="True"
     manager="plone.rightcolumn"
     category="context"
     key="/"
     />

The key attribute matches "/" for site-wide portlets and an absolute Zope path for context-wide ones. For example, if you want to remove all assignments from Plone/news, use:

 <assignment
     purge="True"
     manager="plone.rightcolumn"
     category="context"
     key="/Plone/news"
     />

 

4.9. Properties

Information about the import and export of property sheets.

GenericSetup exports two kinds of property files by default. The properties.xml contains the properties set at the root of your Plone site. The propertiestool.xml contains all of the property sheets that are in the properties_tool. Both of these use the same syntax that will be described here. See the Properties Reference for more detailed information about what these properties do.

The propertiestool.xml is split into a section for each property sheet.

<?xml version="1.0"?>
<object name="portal_properties" meta_type="Plone Properties Tool">
 <object name="navtree_properties" meta_type="Plone Property Sheet">
   <!-- nav properties here -->
 </object>

 <object name="site_properties" meta_type="Plone Property Sheet">
   <!-- site properties here -->
 </object>

 <object name="custom_property_sheet" meta_type="Plone Property Sheet">
   <property name="title" type="string">Custom Properties</property>
   
   <!-- custom_property_sheet props here -->
 </object>
</object>

The property export handles all of the property sheet types. Single value properties are in the following format.

<property name="property_id" type="property_type">property_value</property>

Where the property_id is the id that the property will have in the property sheet and the property_value is the value that the property gets set to. Here are a couple of examples.

<property name="special_name" type="string">This is special</property>
<property name="magic_number" type="int">3</property>

However, there are a couple of exceptions to this behavior.

Boolean

Boolean properties can be set as follows:

<property name="has_truth" type="boolean">true</property>
<property name="has_truth" type="boolean">True</property>
<property name="has_truth" type="boolean">TRUE</property>
<property name="has_truth" type="boolean">Yes</property>
<property name="has_truth" type="boolean">1</property>

The values True, Yes and 1 will end up being true, these are case insensitive. Any other value will be taken as False.

<property name="has_truth" type="boolean">anything besides true yes or 1 here</property>

Lines

Multi valued properties are known as lines properties. Here is an example of a grocery_list property with three values.

<property name="grocery_list" type="lines">
  <element value="beer"/>
  <element value="chips"/>
  <element value="salsa"/>
</property>

Each <element> will become an item in the lines property.

If you want to update existing lines properties then you need to understand the purge option. If you want to add to the list then you will put purge="false" as follows:

<property name="grocery_list" type="lines" purge="false">
  <element value="wine"/>
  <element value="steak"/>
</property>

Now the property will contain the following:

beer
chips
salsa
wine
steak

If the purge option is not explicitly set (it defaults to true) or if it is set to true, then you would get this:

wine
steak

Date

A date property is similar to the string property but interprets the value as a DateTime.

<property name="day_of_infamy" type="date">December 7, 1941</property>

4.10. Resource Registries

Information about the import and export of resource registry settings.

This step let's you register CSS, KSS and JavaScript resources into the the corresponding registries, defining them in cssregistry.xml, kssregistry.xml and jsregistry.xml, respectively.

Let's see an example with the CSS registry. This step lets you register stylesheets in the portal_css tool. This tool is a site-wide registry providing interesting features like conditional inclusion, caching, merging or compression. Check the Resource Registries section in the Theming Manual for more info about them.
An example registration in the cssregistry.xml file would be:

<?xml version="1.0"?>
<object name="portal_css" meta_type="Stylesheets Registry">
 <stylesheet title="" cacheable="True" compression="safe" cookable="True"
     enabled="1" id="pro_members.css" media="screen"
     expression="not: portal/portal_membership/isAnonymousUser"
     rel="stylesheet" rendering="import" 
     insert-before="ploneCustom.css"
     />
</object>

This code will slide in the pro_members.css stylesheet just before the ploneCustom.css one (so overriding its values if there are any collisions) when the user is not anonymous.
Check the Resource Registries section of the Theming Manual for more info about the different options (XML attributes) available.

4.11. Roles and Permissions

Information about the import and export of roles and permissions.

You can create roles and modify permissions using the rolemap.xml GenericSetup import step. For more information on roles and permissions see the Permissions and roles tutorial.

Here is an example of what you will see when you export the rolemap step.

<?xml version="1.0"?>
<rolemap>

  <roles>
    <role name="Anonymous"/>
    <role name="Authenticated"/>
    <role name="Contributor"/>
    <role name="Editor"/>
    <role name="Manager"/>
    <role name="Member"/>
    <role name="Owner"/>
    <role name="Reader"/>
    <role name="Reviewer"/>
  </roles>

  <permissions>

    <permission name="View" acquire="True">
      <role name="Contributor"/>
      <role name="Editor"/>
      <role name="Reader"/>
    </permission>

    <!-- more permissions here -->

  </permissions>

</rolemap>

The rolemap.xml is split into two sections, roles and permissions. Imagine you want to create a new ProUser role in your site. Here is what the rolemap.xml would look like.

NOTE: The rolemap.xml must include both the <roles> and <permissions> tags, even if they have empty contents - otherwise the step will error out.

<?xml version="1.0"?>
<rolemap>
  <roles>
    <role name="ProUser"/>
  </roles>
  <permissions/>
</rolemap>

You can assign the newly created role to existing permissions in the system. Here we add the ProUser role to the View permission.

<permission name="View" acquire="True">
  <role name="Reader"/>
  <role name="Editor"/>
  <role name="Contributor"/>
  <role name="ProUser"/>
</permission>

Note that if you assign roles to a permission using the <permission> directive, it will overwrite existing assignments, so remember to include all the already assigned roles when doing so. The following would change the View permission to only be applied to the ProUser role.

<permission name="View" acquire="True">
  <role name="ProUser"/>
</permission>

The acquire attribute tells Zope wether or not to inherit the permissions from above. The default is False.

Removing roles and permissions

The rolemap handler does not handle the removal of roles or permissions. You would need to write Python code in order to remove a role from the system via your GenericSetup profile.

Permissions are typically created at startup via the package's __init__.py or being defined in zcml.

4.12. Sharing

Info about the sharing tab GenericSetup handler

The GenericSetup handler for the sharing tab, new in Plone 4, allows you to define new local role labels. When you add a new role to your site you may want to assign that role from the sharing tab. The sharing.xml allows us to do this.

The sharing export handler does not export the globally registered utilities. This means that by default there will be no entries in the sharing.xml when it is exported.

As an example, let's say you've added a new role named CopyEditor (see the rolemap reference for more details on adding roles) to your site. This would not be present on the sharing page. To make it show up you would add the following to your sharing.xml.

<?xml version="1.0"?>
<sharing xmlns:i18n="http://xml.zope.org/namespaces/i18n"
         i18n:domain="my.package">
  <role
      id="CopyEditor"
      title="Can edit copy"
      permission="Manage portal"
      i18n:attributes="title"
      />
</sharing>

The sharing.xml file has a container named sharing. Inside of the sharing tag there are role tags. Here is an explanation of what the attributes of the role tag will do.

id
The id is the name of the role that you have defined
title
The title is what will show on the sharing tab to represent this local role
permission
The permission is the Zope permission needed to assign the local role

Modify existing sharing tab entries

You can change existing sharing tab entries by redefining them. All you need to define is the id, then you can change the title and the permission to your liking. In this example we change the title to something funny and probably confusing to the end user. The permission can also be changed, here we changed it to View. If you had access to the sharing page and had the View permission on the item then you could assign the local role.

NOTE: When changing the stock local role entries you are creating a local utility that overrides the globally registered utility.

<?xml version="1.0"?>
<sharing>
  <role
      id="Reviewer"
      title="Content Overlord"
      permission="View"
      />
</sharing>

Removing entries

To remove an entry, just use the remove attribute on a <role /> node:

<role
  remove="True"
  id="Reviewer"
  />

 

4.13. Skins

Information about the import and export of skin paths

For some background about skin layers, read the Skin Layers section of the Theming Manual.

Let's take the skins.xml file of plonetheme.sunburst skins.xml as example:

<?xml version="1.0"?>
<object name="portal_skins" default_skin="Sunburst Theme">

 <object name="sunburst_images"
    meta_type="Filesystem Directory View"
    directory="plonetheme.sunburst:skins/sunburst_images"/>
 <object name="sunburst_templates"
    meta_type="Filesystem Directory View"
    directory="plonetheme.sunburst:skins/sunburst_templates"/>
 <object name="sunburst_styles"
    meta_type="Filesystem Directory View"
    directory="plonetheme.sunburst:skins/sunburst_styles"/>
 <object name="sunburst_js"
    meta_type="Filesystem Directory View"
    directory="plonetheme.sunburst:skins/sunburst_js"/>    

 <skin-path name="Sunburst Theme" based-on="Plone Default">
  <layer name="sunburst_images"
     insert-after="custom"/>
  <layer name="sunburst_templates"
     insert-after="sunburst_images"/>
  <layer name="sunburst_styles"
     insert-after="sunburst_templates"/>
  <layer name="sunburst_js"
     insert-after="sunburst_styles"/>     
 </skin-path>

</object>

Here, the line

<object name="portal_skins" default_skin="Sunburst Theme">

indicates we're dealing with the portal_skins object and sets Sunburst Theme as the default active theme. The later has the same effect of selecting Sunburst Theme in the Themes control panel dialog or in the portal_skins properties in the ZMI.

The <object /> nodes define a new Filesystem Directory View (FSDV):

name
The name of the skin layer as shown in the contents of portal_skins in the ZMI. It usually matches the name of the directory in the filesystem, but doesn't neccessarily have to.
meta_type
Will always be Filesystem Directory View in this context.
directory
 The path to the directory in the filesystem in the format
[yournamespace].[your theme name]:skins/[Your Skin Directory Name]

 

Then, we insert the the previously defined skin layers in a theme. First, we specify we're dealing with the skin named Sunburst Theme, which will inherit the list and order of skins layers from Plone Default:

 <skin-path name="Sunburst Theme" based-on="Plone Default">

Next, we insert each skin layer in the appropiate place.

  <layer name="sunburst_images" insert-after="custom"/>

You can use the insert-after and insert-before attributes with the name of an already present skin layer to control the placement. If you want to insert a layer at the top of the stack, use

  <layer name="layer_name" insert-before="*"/>

If you don't specify any insert-after nor insert-before attributes, the specified layer will be inserted at the bottom of the stack.

4.14. Structure

Information about the import of site structure

Despite this import step have been available since long time ago, the syntax is complex and underdocumented, so it's not recommended for use anymore. Use a custom import step with a Python handler and invokeFactory, getters and setters, etc. instead.

If you're still interested on this, you can check the article Make a product install a folder structure in the site.

4.15. Tools

Information about tools import

This import step registers a set of tools in the site, instantiating them at the root if they're missing or their class doesn't match the existing one.

The syntax of the toolset.xml file is very simple:

<?xml version="1.0"?>
<tool-setup>
 ...
 <required tool_id="portal_catalog"
           class="Products.CMFPlone.CatalogTool.CatalogTool"/>
 ...
</tool-setup>

This snippet would instantiate the famous portal_catalog object of the Products.CMFPlone.CatalogTool.CatalogTool class.

The most noticeable difference between a tool and an utility (in the Zope sense) is that tools are persistent objects that exist as content in the ZODB, while utilities are registered either site-wide or locally, but they are not listed as normal content and you won't be able to find them as such using the ZMI.

4.16. Types

Information about the import and export of content-types information.

4.17. Viewlets

Information about the import and export of viewlet settings

You can insert, sort and hide viewlets inside viewlet managers using a viewlets.xml file.

You will find detailed information about this in the tutorial Customizing the viewlets in main_template.

4.18. Workflow

Information about the workflow importer and exporter

You can export and import workflows and their settings this import step. The syntax is rather complex and verbose, so we recommend you to create and adjust the workflow settings manually, export them from the portal_setup tool as described in Using GenericSetup Efficiently and editing the resulting XML later.

You can declare and bind/unbind content-types to a certain workflow chain in the workflow.xml file. For example, the following snippet would register a workflow named my_workflow, set it as the default one, and unbind the My Type content-type from any workflow (including the default one):

<?xml version="1.0"?>
<object name="portal_workflow" meta_type="Plone Workflow Tool">
 <object name="my_workflow" meta_type="Workflow"/>
 <bindings>
  <default>
   <bound-workflow workflow_id="my_workflow" />
  </default>
  <type type_id="My Type" />
 </bindings>
</object>

If you want to bind a particular content-type to a particular workflow, use the syntax:

<bindings>
...
  <type type_id="My Type">
    <bound-workflow workflow_id="my_workflow"/>
  </type>
...
</bindings>

Once you've declared a workflow, you need to define it. Inside a folder named workflows in your profile, add a folder matching the name of your declared workflow and then a definition.xml file inside it. In our example above, profiles/default/workflows/my_workflow/definition.xml.

An short and simple definition.xml file looks like:

<?xml version="1.0"?>
<dc-workflow workflow_id="myt_workflow"
             title="My Content"
             state_variable="review_state"
             initial_state="draft">


 <!-- Permissions being managed -->
 <permission>View</permission>


 <!-- Workflow states, available transitions and permissions mapping -->
 <state state_id="draft" title="Draft">
  <exit-transition transition_id="publish"/>
  <permission-map name="View" acquired="False">
   <permission-role>Editor</permission-role>
   <permission-role>Contributor</permission-role>
  </permission-map>
 </state>

 <state state_id="published" title="Published">
  <exit-transition transition_id="retract"/>
  <permission-map name="View" acquired="False">
   <permission-role>Anonymous</permission-role>
   <permission-role>Member</permission-role>
  </permission-map>
 </state>


 <!-- Transitions between states, including guard conditions -->
 <transition transition_id="publish"
             title="Contributor publishes"
             new_state="published" trigger="USER"
             before_script="" after_script="">
  <action url="%(content_url)s/content_status_
                    modify?workflow_action=publish"
          category="workflow">Publish</action>

  <guard>
   <guard-permission>Publish content</guard-permission>
  </guard>
 </transition>

 <transition transition_id="retract"
             title="Contributor retracts"
             new_state="draft" trigger="USER"
             before_script="" after_script="">
  <action url="%(content_url)s/content_status_
                    modify?workflow_action=retract"
          category="workflow">Retract</action>

  <guard>
   <guard-permission>Retract content</guard-permission>
  </guard>
 </transition>

</dc-workflow>

First, we define the permissions we're going to manage (View in this case).

Later, we define the different available states, together with their role mapping and available transitions.

Last, we define what each transition should perform. An user must have the indicated guard permission in the context to trigger the associated transition.