Plone Add-On Development Configuration Panel – Part 1

If you are developing an add-on for the Plone Content Management System (CMS) there will be regularly the need for some configuration options, e.g. you want the user to choose from some categories or versions. And you don’t want to hard code this options and make you program more flexible.

Thus you need some fields where you could provide this entries (options) and a place to store them. The first option to do this would be inside the add-on objects itself, e.g. in the root content object. There you could add such fields, index there values into the Plone ‘portal_catalog’ and query them from there. But I think there is a much better option to set such options. You could create a controlpanel and add this to the ‘site configuration’ page, dedicated to the admin and site admin of a Plone site. There is already a section for add-on configuration entries available.

It’s very easy to add new configuration fields to the controlpanel. There are fields available for lists, tuple, Textline and Text etc. The values of the fields could be stored in Plone’s ‘Configuration Registry’ and taken with features from the Plone api from there very easy.

Here a first example for the source code of a controlpanel:

# -*- coding: utf-8 -*-
from collective.templates import _
from plone.app.multilingual.dx import directives
from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper
from plone.app.registry.browser.controlpanel import RegistryEditForm
from plone.supermodel import model
from plone.z3cform import layout
from Products.CMFPlone.utils import safe_unicode
from zope import schema
from zope.interface import Interface


class ICollectivetemplatesControlPanel(Interface):
    available_category = schema.Tuple(
        title=_(safe_unicode('Available Categories')),
        default=('Business',),
        value_type=schema.TextLine())

    allowed_templatefileextension = schema.TextLine(
        title=_(safe_unicode(
                   'Allowed template file extensions')),
        description=_(safe_unicode(
           'Fill in the allowed (...).')),
        default=safe_unicode('ott|ots|otp|otg'),
    )

    legal_disclaimer = schema.Text(
        title=_(safe_unicode(
                    'Text of the Legal Disclaimer and Limitations')),
        description=_(safe_unicode(
            'Enter the text of the legal disclaimer (...).')),
        default=_(safe_unicode(
            'Fill in the legal disclaimer, (...).')),
        required=False,
    )

(...)

class CollectivetemplatesControlPanelForm(RegistryEditForm):
    schema = ICollectivetemplatesControlPanel
    schema_prefix = 'collectivetemplates'
    label = u'Collective Templates Settings'


CollectivetemplatesControlPanelView = layout.wrap_form(
    CollectivetemplatesControlPanelForm, ControlPanelFormWrapper)

The code above showed different field types for the configuration options. There are the ‘Tuple’ which contains a listing of values. Because the value type is schema.Textline every line of the field contains a single value of the listing.

Then there is a TextLine field for in this example a single value of allowed file extensions. The different allowed values are seperated by a pipe in this case.

The last field is Text field which is able to get a text with more than one line. In this case a text which should be shown to a user (contributor) of a site. It would be possible to use also a RichText field inside this controlpanel, but there will pop up an error message once you try to write the value of such field to the Plone Configuration Registry.

But the use of a RichText field isn’t necessary in this case. If you want to display the content of a Text field on a webpage inside Plone you could write the text including HTML tags, e.g. for headings and paragraphs.

I’ll explain in an upcomming blog post how to add this controlpanel to the site configuration page and to write the values of the fields to the Plone configuration registry.

The last lines of the above source code example create the registry form from the above schema.