Thanks, I saw that mentioned in a couple of places, but this code worked nicely for what I needed (to create the folders if needed and to constrain the addable types).
import plone.api as api
from Products.CMFPlone.interfaces import constrains
from plone.base.interfaces.constrains import ISelectableConstrainTypes
def install(context):
"""Post install script"""
portal = api.portal.get()
if not portal.hasObject('notes'):
notes_folder = api.content.create(
container=portal,
type='Folder',
id='notes',
title='Notes',
description='A folder to contain all notes.'
)
else:
notes_folder = portal['notes']
# Set constraints on the notes folder
constraints = ISelectableConstrainTypes(notes_folder)
constraints.setConstrainTypesMode(constrains.ENABLED)
constraints.setLocallyAllowedTypes(['note'])
constraints.setImmediatelyAddableTypes(['note'])
if not portal.hasObject('tools'):
tools_folder = api.content.create(
container=portal,
type='Folder',
id='tools',
title='Tools',
description='A folder to contain all tools.'
)
else:
tools_folder = portal['tools']
# Set constraints on the tools folder
constraints = ISelectableConstrainTypes(tools_folder)
constraints.setConstrainTypesMode(constrains.ENABLED)
constraints.setLocallyAllowedTypes(['tool'])
constraints.setImmediatelyAddableTypes(['tool'])
if not portal.hasObject('images'):
images_folder = api.content.create(
container=portal,
type='Folder',
id='images',
title='Images',
description='A folder to contain all images.'
)
else:
images_folder = portal['images']
# Set constraints on the images folder
constraints = ISelectableConstrainTypes(images_folder)
constraints.setConstrainTypesMode(constrains.ENABLED)
constraints.setLocallyAllowedTypes(['Image'])
constraints.setImmediatelyAddableTypes(['Image'])
if not portal.hasObject('documents'):
documents_folder = api.content.create(
container=portal,
type='Folder',
id='documents',
title='Documents',
description='A folder to contain all documents.'
)
else:
documents_folder = portal['documents']
# Set constraints on the documents folder
constraints = ISelectableConstrainTypes(documents_folder)
constraints.setConstrainTypesMode(constrains.ENABLED)
constraints.setLocallyAllowedTypes(['File'])
constraints.setImmediatelyAddableTypes(['File'])
I figured it might not work to try to constrain the addable types to the PloneSite, and, sure enough, it did not:
# Set constraints on the site root
constraints = ISelectableConstrainTypes(portal)
allowed_types = constraints.getLocallyAllowedTypes()
if 'note' in allowed_types:
allowed_types.remove('note')
if 'tool' in allowed_types:
allowed_types.remove('tool')
constraints.setConstrainTypesMode(constrains.ENABLED)
constraints.setLocallyAllowedTypes(allowed_types)
constraints.setImmediatelyAddableTypes(allowed_types)
TypeError: ('Could not adapt', <PloneSite at /Plone>, <InterfaceClass plone.base.interfaces.constrains.ISelectableConstrainTypes>)
Changing the Note (or Tool) content type's global_allow property indeed does it everywhere, including in the folders where I do want them addable.
Is there another way to prevent adding them at the site root but still have them addable in folders?