Current

This document is valid for the current version of Plone.

Make a product install a folder structure in the site

by Kees Hink last modified Oct 24, 2012 09:44 AM
This documentation has moved to http://developer.plone.org/content/creating.html#creating-content-using-generic-setup

Purpose

You want your product to install a folder structure in the site when the product is installed. For example, if you have a product which creates objects, you might want to create a special folder for them. Of course, you could do all this programmatically, but there's a much simpler way: Generic Setup has alredy taken care of it.

Prerequisities

You'll need a basic understanding of Generic Setup.

Step by step

  1. In your product's profiles/default folder, create a directory called 'structure'. 
  2. To create a top-level folder with id 'installed-by-product', add a directory of that name to the structure folder.
  3. Create a file called .objects in the 'structure' directory
  4. Create a file called .properties in the 'installed-by-product' directory
  5. Create a file called .preserve in the 'structure' directory

.objects registers the folder to be created:

installed-by-product,Folder

.properties sets properties of the folder to be created:

[DEFAULT]
description = Folder for imported Projects
title = Imported Projects

.preserve will make sure the folder isn't overwritten if it already exists.

installed-by-product

Troubleshooting

Ids instead of titles

You may notice that the new generated content's title appears to be set to its id. In this case, the catalog needs to be updated. You can do this through the ZMI, in 'portal_catalog'.

You could automate this process by adding a GS import step in configure.zcml, which looks like this:

<genericsetup:importStep
       name="my.policy_updateCatalog"
       title="Update catalog"
       description="After creating content (from profiles/default/structure), the catalog needs to be updated."
       handler="my.policy.setuphandlers.updateCatalog">
     <depends name="content"/>
   </genericsetup:importStep> 

This is the preferred way to define dependencies for import profiles: The import step declares its dependency on the content import step. 'content' is the name for the step which creates content from profiles/default/structure.You could then add a method which updates the catalog in the product's setuphandlers.py:

def updateCatalog(context, clear=True):
    portal = context.getSite()
    logger = context.getLogger('my.policy updateCatalog')
    logger.info('Updating catalog (with clear=%s) so items in profiles/default/structure are indexed...' % clear )
    catalog = portal.portal_catalog
    err = catalog.refreshCatalog(clear=clear)
    if not err:
        logger.info('...done.')
    else:
        logger.warn('Could not update catalog.')

Further information

See http://vanrees.org/weblog/creating-content-with-genericsetup

If you need more control over the created content, you might want to consider this blog post.


Contribute

Something wrong or out of date? Anybody can edit or create a new article in the knowledge base. Simply create an account on this site, log in, and click the Edit button to contribute.