Wednesday, February 4, 2009

Creating portal content in

Updated; see

To add portal content, you can use GenericSetup's profiles/default/structure mechanism. However, this does not allow to set the default view of folders. To gain more flexibility, i added some methods to

from Products.CMFPlone.utils import _createObjectByType

def deletePloneFolders(p):
"""Delete the standard Plone stuff that we don't need
# Delete standard Plone stuff..
existing = p.objectIds()
itemsToDelete = ['Members', 'news', 'events']
for item in itemsToDelete:
if item in existing:

def createFolderStructure(portal):
"""Define which objects we want to create in the site.
profile_children = [
{ 'id': 'meters',
'title': 'My Meters',
'description': '',
'type': 'Folder',
'layout': 'metertypeform',
top_folders = [
{ 'id': 'profile',
'title': 'My Profile',
'description': '',
'type': 'Folder',
'layout': 'wm-profile',
'children': profile_children,
{ 'id': 'meterreadings',
'title': 'My Meter Readings',
'description': '',
'type': 'Folder',
'layout': 'meterreadings',
{ 'id': 'analysis',
'title': 'My Consumption',
'description': '',
'type': 'Folder',
'layout': 'analysis',
createObjects(parent=portal, children=top_folders)

def createObjects(parent, children):
"""This will create new objects, or modify existing ones if id's and type
parent.plone_log("Creating %s in %s" % (children, parent))
existing = parent.objectIds()
parent.plone_log("Existing ids: %s" % existing)
for new_object in children:
if new_object['id'] in existing:
parent.plone_log("%s exists, skipping" % new_object['id'])
_createObjectByType(new_object['type'], parent, \
id=new_object['id'], title=new_object['title'], \
parent.plone_log("Now to modify the new_object...")
obj = parent.get(new_object['id'], None)
if obj is None:
parent.plone_log("can't get new_object %s to modify it!" % new_object['id'])
if obj.Type() != new_object['type']:
parent.plone_log("types don't match!")
children = new_object.get('children',[])
if len(children) > 0:
createObjects(obj, children)

def setupVarious(context):

# Ordinarily, GenericSetup handlers check for the existence of XML files.
# Here, we are not parsing an XML file, but we use this text file as a
# flag to check that we actually meant for this import step to be run.
# The file is found in profiles/default.

portal = context.getSite()

if context.readDataFile('MyProduct.theme_various.txt') is None:

# Add additional setup code here

No comments: