Installing the product

Description

Ensuring the product elements (types, browser layers, resources) are correctly installed.

In this part, we will provide the code to be executed when the integrator “adds”, i.e. installs, the InstantMessage product to the Plone site. This aspect of the product code is called the “Extension Profile” (or “Setup Profile”) and is managed under the hood by a machinery called GenericSetup.

For more about GenericSetup, its possibilities, and how a developer uses it, read the GenericSetup tutorial.

The setup profile files (profiles/default)

The setup profile is composed of a set of GenericSetup XML files containing setup declarations.

Type declaration and definition

First, we provide the files needed for adding the types to CMF’s types registry (portal_types): types.xml and types/InstantMessage.xml.

In types.xml, within the <object name="portal_types" ... /> element, add the setup code for the type(s) you want to install:

<?xml version="1.0"?>
<object name="portal_types" meta_type="Plone Types Tool">
 <property
    name="title">Controls the available content types in your portal</property>
 <object name="InstantMessage"
    meta_type="Factory-based Type Information with dynamic views"/>
</object>

The name property of the <object> node constitutes the called portal type name of the content-type, a CMF concept which supports two things:

  1. Dynamic typing: objects can change their content type during their lifetime. To do this use _setPortalTypeName(<type>).
  2. You can have arbitrarily many different content types using the same base class (and having therefore the same meta_type) but differing in their Factory Type Information (FTI) settings.

The portal type name was formerly set in a content-type class attribute called portal_type, which is no longer necessary.

The name of the file inside the profiles/default/types folder must match the portal type name, with spaces converted to underscores whenever necessary. So, in`` types/InstantMessage.xml``, add the code for the InstantMessage FTI object:

<?xml version="1.0"?>
<object name="InstantMessage"
   meta_type="Factory-based Type Information with dynamic views"
   i18n:domain="example.archetype" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
  <property name="title" i18n:translate="">Example AT - InstantMessage</property>
  <property name="description"
    i18n:translate="">An example type (InstantMessage) discussed in the AT Developer Manual.</property>

In these first lines we give the content-type a title and a description.

The title property indicates the user-friendly name of the content-type. This is what’s supposed to be used in the user interface, and can be accessed using the <fti>.title_or_id() or the Type() methods, which both return the content-type title if it exists or the content-type id otherwise. Like portal type, this property was formerly set in a the content-type class attribute called archetype_name, which is no longer neccessary.

<property name="content_meta_type">InstantMessage</property>
<property name="content_icon">document_icon.gif</property>
<property name="product">example.archetype</property>
<property name="factory">addInstantMessage</property>

The meta_type property of the object is a Zope concept to organize object classification or containment. For historical reasons, it is used in CMF in some places because first versions of CMF didn’t have today’s portal_type. Also note that Archetypes uses the content-type class name as the meta_type value, unless given explicitly.

The content_icon property specifies the icon image file which will be shown in the Plone UI for this content-type. This icon image file must be accessible from the context of the content-type, and therefore should be placed into a CMF skin layer (the CMF way) or in a browser resource directory (the Zope 3 way).

The factory property indicates the factory function which will be used to create and initialize new content objects of this type. This factory is automatically generated by the Archetypes framework, when the product is initialized (via the code in the startup module), and is always named add<content-meta-type>. The factory is also associated with a certain product by means of the product property.

<property name="immediate_view">atct_edit</property>
<property name="global_allow">True</property>
<property name="filter_content_types">False</property>
<property name="allow_discussion">False</property>

The global_allow property determines if the content-type will be available to be added from anywhere in the site.

The filter_content_types property, paired with allowed_content_types, controls what content-types will be addable inside the current one.

With allow_discussion, we specify whether or not comments will be allowed by default on this content-type.

<property name="default_view">@@instantmessage_view</property>
<property name="view_methods">
  <element value="@@instantmessage_view" />
</property>
<alias from="(Default)" to="@@instantmessage_view" />
<alias from="edit" to="atct_edit" />
<alias from="sharing" to="@@sharing" />
<alias from="view" to="@@instantmessage_view" />

Here we define CMF views (templates) and aliases that map content-type methods to views.

  <action title="View" action_id="view" category="object" condition_expr=""
    url_expr="string:${object_url}/" visible="True">
    <permission value="View" />
  </action>
  <action title="Edit" action_id="edit" category="object" condition_expr=""
    url_expr="string:${object_url}/edit" visible="True">
    <permission value="Modify portal content" />
  </action>
</object>

The <action> elements register type-specific actions for the content-type. The object category makes the render as tabs in the Plone UI.

  • The url_expr is a TALES expression that defines the URL from where the action will be triggered and should match one of the method aliases defined above. Hence, the edit action points to string:${object_url}/edit, which means that if you are at /path/to/object and click edit, you will go to /path/to/object/edit. /edit then gets recognized as a method alias, which points to the page template atct_edit, causing Zope to render /path/to/object/atct_edit.
  • The <permission /> element specifies a guard permission for this action. If the user’s role doesn’t have this permission, the action won’t be available and the corresponding action tab won’t be shown.
  • In addition to the former criteria, the condition_expr is a TALES expression which will be evaluated to decide if the action is available or not.
  • The visible attribute indicates wheter the action tab will be visible or hidden. If it’s set to False, the tab won’t appear even when the action is available, but the exposed page will still be accesible from the associated URL.

Notes:

  • Defining new content-type actions this way, i.e. using GenericSetup, supersedes the old updateActions function from ATContentTypes.content.base.
  • Don’t worry. You don’t have to type all this XML each time you create a new content-type; since most of it is boilerplate (XML is very verbose) you can copy & paste an already working example (like the CMFPlone ones) and modify only the changing bits.

Roles - Permissions mapping

For our content type(s) to be usable, we need to assign the required “Add” permission to the Plone site’s default roles: Contributor, Owner, and Manager. This is done using the rolemap.xml file as follows:

<?xml version="1.0"?>
<rolemap>
    <permissions>
        <permission name="example.archetype: Add InstantMessage" acquire="True">
          <role name="Manager"/>
          <role name="Owner"/>
          <role name="Contributor"/>
        </permission>
    </permissions>
</rolemap>

Browser skin layer

In order to install our browser skin layer, we also add a browserlayer.xml file with the following code:

<?xml version="1.0"?>
<layers>
  <layer name="example.archetype"
         interface="example.archetype.interfaces.IInstantMessageSpecific" />
</layers>

Registering our setup profile

This last step ensures everything can work. We update the package’s configure.zcml file with the code snippet that will load the extension profile:

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:five="http://namespaces.zope.org/five"
    xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
    i18n_domain="example.archetype" >

   <five:registerPackage package="." initialize=".initialize" />

   <include package=".browser" />

   <genericsetup:registerProfile
      name="default"
      title="Example Archetype content - InstantMessage"
      directory="profiles/default"
      description="Extension profile for Example AT - InstantMessage"
      provides="Products.GenericSetup.interfaces.EXTENSION"
      />

</configure>

Restarting Zope

Now that you have a first version of your product ready to be tested, and installed via your buildout, you need to (re)start Zope.

Quick-installing the product

Back in the Plone configuration (or Plone control panel), when you visit the “Add/Remove Products” interface or the portal_quickinstaller tool through the ZMI (at the root of the site), you can see the product show up under the category of “installable products”.

Select and click the button to install the product. If everything goes fine, the product should be installed, and you’re ready to start using it!