This section of Plone content management system Developer Documentation is no longer under active maintance. The section is included as the reference for older technologies (Plone 2.x, Plone 3.x). Some of the practices described in this documents may still work, but are not recommended to be used in your active Plone development. Use at your own risk.
If you arrived at this page by a web search we recommend to also see the Plone Developer Documentation front page .
Plone's content type subsystems and creating new content types programmatically.
Plone has two kind of content types subsystems:
Flexible architecture allows other kinds of content type subsystems as well.
Plone maintains available content types in the portal_types tool.
portal_types is a folderish object which stores type information as child objects, keyed by the portal_type property of the types.
portal_factory is a tool responsible for creating the persistent object representing the content.
Often you need to ask the user to choose specific Plone content types.
Plone offers two Zope 3 vocabularies for this purpose:
If you need to build a vocabulary of user-selectable content types in Python instead, here's how:
from Acquisition import aq_inner from zope.app.component.hooks import getSite from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm from Products.CMFCore.utils import getToolByName def friendly_types(site): """ List user-selectable content types. We cannot use the method provided by the IPortalState utility view, because the vocabulary factory must be available in contexts where there is no HTTP request (e.g. when installing add-on product). This code is copied from https://github.com/plone/plone.app.layout/tree/master/plone/app/layout/globals/portal.py @return: Generator for (id, type_info title) tuples """ context = aq_inner(site) site_properties = getToolByName(context, "portal_properties").site_properties not_searched = site_properties.getProperty('types_not_searched', ) portal_types = getToolByName(context, "portal_types") types = portal_types.listContentTypes() # Get list of content type ids which are not filtered out prepared_types = [t for t in types if t not in not_searched] # Return (id, title) pairs return [ (id, portal_types[id].title) for id in prepared_types ]
These instructions apply to Archetypes-based content types.
Creating types by hand is not worth the trouble. Please use a code generator to create the skeleton for your new content type.
The content type name must not contain spaces. Neither the content type name or the description may contain non-ASCII letters. If you need to change these please create a translation catalog which will translate the text to one with spaces or international letters.
Creating types by hand is not worth the trouble.
There exist solutions for non-programmers and Plone novices to create their content types more easily.
Implictly allowed is a flag specifying whether the content is globally addable or must be specifically enabled for certain folders.
The following example allows creation of Large Plone Folder anywhere at the site (it is disabled by default). For available properties, see TypesTool._advanced_properties.
portal_types = self.context.portal_types lpf = portal_types["Large Plone Folder"] lpf.global_allow = True # This is "Globally allowed" property
For the instances of some content types, the user may manually restrict which kinds of objects may be added inside. This is done by clicking the Add new... link on the green edit bar and then choosing Restrictions....
This can also be done programmatically on an instance of a content type that supports it.
First, we need to know whether the instance supports this.
from Products.Archetypes.utils import shasattr # To avoid acquisition if shasattr(context, 'canSetConstrainTypes'): # constrain the types context.setConstrainTypesMode(1) context.setLocallyAllowedTypes(('News Item',))
If setConstrainTypesMode is 1, then only the types enabled by using setLocallyAllowedTypes will be allowed.
The types specified by setLocallyAllowedTypes must be a subset of the allowable types specified in the content-type's FTI (Factory Type Information) in the portal_types tool.
If you want the types to appear in the :guilabel: Add new.. dropdown menu, then you must also set the immediately addable types. Otherwise, they will appear under the more submenu of Add new...
The immediately addable types must be a subset of the locally allowed types.
To retrieve information on the constrained types, you can just use the accessor equivalents of the above methods.
context.getConstrainTypesMode() context.getLocallyAllowedTypes() context.getImmediatelyAddableTypes() context.getDefaultAddableTypes() context.allowedContentTypes()
Be careful of Acquisition. You might be acquiring these methods from the current instance's parent. It would be wise to first check whether the current object has this attribute, either by using shasattr or by using hasattr on the object's base (access the base object using aq_base).
The default addable types are the types that are addable when constrainTypesMode is 0 (i.e not enabled).
For more information, see Products/CMFPlone/interfaces/constraints.py
The source code of this file is hosted on GitHub. Everyone can update and fix errors in this document with few clicks - no downloads needed.
For basic information about updating this manual and Sphinx format please see Writing and updating the manual guide.