The document discusses using Buildout, GenericSetup, and a policy package to create repeatable Plone site environments, including setting up profiles for installation and upgrades, content packages for initial content, and a Plone site recipe for Buildout to automate site creation. It also provides an example of setting up a policy package, various profiles, and using GenericSetup and upgrades to manage a site configuration.
9. Human Err0r PLONE SYMPOSIUM EAST 2012
“Hey Bob, did you run the fizzbang.widget profile
on production”
“I think so, Doug”
“Do you know why the client is yelling at me
right now?”
“Maybe I didn’t, let me fix that real quick”
11. Create the package* PLONE SYMPOSIUM EAST 2012
$ cd path/to/buildout/src
$ zopeskel sfu_policy pse12.policy
$ cd pse12.policy
.. git init / add / etc ...
* This example uses sixieskel for brevity,
you might use the “plone” template
34. Setuphandlers PLONE SYMPOSIUM EAST 2012
from sixfeetup.utils import helpers as sfutils
def importVariousInitial(context):
"""Run the setup handlers for the initial profile"""
if context.readDataFile('pse12_policy-initial.txt') is None:
return
members = [
{'id': 'staff',
'password': 'staff',
'roles': ['Manager', 'Member'],
'properties': {
'email': 'changeme@example.com',
'fullname': 'Site Staff',
'username': 'staff'
}
}
]
sfutils.addUserAccounts(members)
35. Setuphandlers PLONE SYMPOSIUM EAST 2012
<genericsetup:importStep
name="pse12.policy: initial"
title="pse12.policy: Various Initial steps"
description="Initial Setup handlers for pse12.policy"
handler="pse12.policy.setuphandlers.importVariousInitial">
<depends name="content"/>
</genericsetup:importStep>
36. Setuphandlers PLONE SYMPOSIUM EAST 2012
from sixfeetup.utils import helpers as sfutils
def importVarious(context):
"""Run the setup handlers for the default profile"""
if context.readDataFile('pse12_policy-default.txt') is None:
return
# automagically run a plone migration if needed
sfutils.runPortalMigration()
# automagically run the upgrade steps for this package
sfutils.runUpgradeSteps(u'pse12.policy:default')
37. Setuphandlers PLONE SYMPOSIUM EAST 2012
from sixfeetup.utils import helpers as sfutils
def importVarious(context):
"""Run the setup handlers for the default profile"""
if context.readDataFile('pse12_initialcontent-default.txt') is None:
return
# automagically run the upgrade steps for this package
sfutils.runUpgradeSteps(u'pse12.initialcontent:default')
38. Upgrades PLONE SYMPOSIUM EAST 2012
<!-- pse12.initialcontent upgrades.zcml -->
<genericsetup:upgradeStep
title="Set up intranet section"
description=""
source="001"
destination="002"
handler="pse12.initialcontent.upgrades.intranet_setup"
sortkey="10"
profile="pse12.initialcontent:default"
/>
<genericsetup:upgradeStep
title="Set up the default pages"
description=""
source="001"
destination="002"
handler="pse12.initialcontent.upgrades.default_pages"
sortkey="20"
profile="pse12.initialcontent:default"
/>
39. from zope.app.component.hooks import getSite
PLONE SYMPOSIUM EAST 2012
from Products.CMFCore.utils import getToolByName
from sixfeetup.utils import helpers as sfutils
def intranet_setup(context):
"""Set up the placeful workflow for the intranet
"""
portal = getSite()
# If the intranet doesn't exist, bail out
if 'intranet' not in portal.objectIds():
return
intranet = portal['intranet']
# If the placeful workflow is already in place, bail out
if '.wf_policy_config' in intranet.objectIds():
return
placeful_workflow = getToolByName(portal, 'portal_placeful_workflow')
product = 'CMFPlacefulWorkflow'
intranet.manage_addProduct[product].manage_addWorkflowPolicyConfig()
config = placeful_workflow.getWorkflowPolicyConfig(intranet)
policy = 'intranet'
config.setPolicyBelow(policy=policy)
config.setPolicyIn(policy=policy)
# Make everything in the intranet `private`
path = '/'.join(intranet.getPhysicalPath())
sfutils.publishEverything(context, path, 'hide')
40. from zope.app.component.hooks import getSite
PLONE SYMPOSIUM EAST 2012
def default_pages(context):
"""There is a bug in quintagroup.transmogrifier that prevents
the default page from being set. We will handle it here
instead.
"""
portal = getSite()
items = {
'about': dict(
id='default_page',
type='string',
value='about-us'),
'blog': dict(
id='layout',
type='string',
value='blog_view'),
}
for path, prop in items.items():
obj = portal.unrestrictedTraverse(path, None)
# If the object doesn't exist, bail out
if obj is None:
continue
target_obj = None
if prop['id'] == 'default_page':
target_obj = obj.unrestrictedTraverse(prop['value'], None)
# Bail out if the default page target does not exist
if target_obj is None:
continue
obj._setProperty(prop['id'], prop['value'], prop['value'])
if target_obj is not None:
# ensure that it doesn't show in the navigation
target_obj.reindexObject()