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 thus make you program more flexible.

Therefore 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 their 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.

Further Steps Forward On Conference Add-on

I worked on a Plone add-on to manage conferences. I already created such an add-on to run the LibreOffice conferences in Berlin (2012) and Milano (2013). But this add-on was build against a former version of Plone and Python 2. It used the Grok style which could have some side effects. Thus I decided to move away from Grok style for an upgrade / a new setup of the add-on.

I already moved all modules and active functions away from Grok and reordered the structure of the add-on. I added a new configuration panel to the administration page. I could also fix relations and the indexing. You could get the code from Github at: https://github.com/collective/collective.conferences.

Worked On Plone Conference Add-On And With Navigation Root

I worked further on a Plone add-on to manage conferences and had to work with the navigation root of a Plone site. I moved this navigation root to the container object of the conference add-on. The navigation worked as expected yet (the objects in top container made it to the main navigation menubar), but the login and register links at the top of the site didn’t work anymore. Thus I had to edit the links of this actions / portal_actions inside the ‘Site Setup’ or the Plone ‘Management Interface’. I added a short howto about this.

Working On Plone Conference Add-On

I created a Plone conference add-on a longer time ago, which was used to run two LibreOffice conferences. I published the code of this add-on on the Plone collective Github account.

This add-on was created and used within Plone 4 and the Grok method. This is not the usal way to develop on Plone anymore thus I decided to first drop all grok ties and replace them with other Plone methods, especially make better use of configure.zcml. I’ll finish this work during the next days.

The goal of my work is the migration of the conference add-on to Plone 5.2.x and Python 3 and add new features afterwards to support the work of organizers of analog and online conferences.

The code of the conference add-on is available at: https://github.com/collective/collective.conferences

New Releases Of Collective.Addons And Collective.Templates

I added a feature to choose if the name and / or the contact e-mail address of an addon project should be published on the projects page during the last days. Today I created a release from this changes and published it on the Cheeseshop (https://pypi.org): https://pypi.org/project/collective.addons/

The source code of this Plone add-on is available on its Github repository:
https://github.com/collective/collective.addons

In addition I made a small bugfix release for the Plone add-on collective.templates and published it to on pypi.org:
https://pypi.org/project/collective.templates/
The source code of this add-on could be cloned from Github at:
https://github.com/collective/collective.templates.

New Release Of Collective.Templates

I worked further on the source code of the Plone add-on collective.templates and added a feature to display the username and the e-mail address of a project owner on his/her choice. The new release contains also an improved user documentation.

You could download the new release from the Cheeseshop (https://pypi.org):
https://pypi.org/project/collective.templates/
The source code is available from the Github repository of the Plone collective:
https://github.com/collective/collective.templates

New Releases Of TDF.Templateuploadcenter and TDF.Extensionuploadcenter

I worked on some improvements of the code of the Plone add-ons tdf.templateuploadcenter and tdf.extensionuploadcenter. This add-ons were used to drive the current LibreOffice extensions and templates website.

I moved all unicode strings to ‘safe_unicode’ strings to make it more smooth to migrate the content of the current website to the current version of Plone, 5.2, and Python 3.x.

I published a new release of the add-on tdf.templateuploadcenter (https://pypi.org/project/tdf.templateuploadcenter/) on the Cheeseshop (https://pypi.org) during the weekend. Today I submitted a new release of the add-on tdf.extensionuploadcenter on the Cheeseshop (https://pypi.org/project/tdf.extensionuploadcenter/).

The source code of both Plone add-ons is available in their Github repositories:
https://github.com/andreasma/tdf.templateuploadcenter
https://github.com/andreasma/tdf.extensionuploadcenter

Worked On Collective.ClamAV

I worked with the Plone add-on for virus scanning yesterday and evaluated an issue with a new feature in the Plone add-on plone.formwidget.namedfile. If a file field was not changed (no replacing upload) the return is ‘NOT_CHANGED’ and validator module of collective.clamav was not able to get any data to scan. But there was no need to run a scan in such a situation and thus I added a appropriate check to the validator module. There will be no virus scanning for unchanged file fields anymore.

My changes are already in the Github repository of collective.clamav available: https://github.com/collective/collective.clamav.

The add-on is compatible with Plone 5.2 and Python 3.

LibreOffice Extensions Website Repository Updated To Python 3

I worked on the complete migration of the LibreOffice extensions and templates website repository to Python 3 and Plone 5.2.x during the last days. I was able to upgrade the staging (development / single instance) buildout first. I worked on some Plone add-ons to reach this goal in my spare time during the last weeks.

But for the success of the migration to Python 3 and Plone 5.2.x is necessary a working production buildout. Thus I worked on the live.cfg buildout script for the site and created a new version of it: live2.cfg. I used this new script for the setup of a pure zeoserver with four instances. I could also add the supervisor controller to start and stop the zeoserver and its instances.

Supervisor monitor on my local Plone 5.2.x Python 3 buildout / environment

Then I worked on adding the support of Varnish to it. I used the add-on plone.recipe.varnish from the Github repository for that and changed Varnish to the a current LTS version 6.0.6. I could start varnishd with supervisor although I got an error message with supervisorctl status for it. The Varnish log stated that it could not get the socket of the port, it is configured to run on.

I looked with netstat -pln into the processes running on my PC and found varnishd running and listening. Thus Varnish had been started, but supervisor lost control over it. I was not able to stop Varnish with a supervisorctl command.

I worked further on the migration of HAProxy to the new Python 3 setup. I got a hint from a member of the Plone community that he already created a working branch of plone.recipe.haproxy for Python 3. I changed my buildout scripts to use this branch and I could build and run HAProxy too. But HAProxy didn’t get in contact with Varnish and the zeoserver instances in my setting. It stated that this instances were not running / available, although they are.

I got another hint from this community member and changed my buildout further. I changed the ‘bind’ Varnish configuration line to point to the Haproxy port of my buildout setting. The error message from Varnish disappeared. I was under control of supervisor yet.

Then I read in a blog about an issue of the HAProxy configuration, if it checks via http for the availability of Plone instances. I removed this option (httpchk) from the haproxy.conf file and everything went green. I could finish the migration to Python 3 and Plone 5.2.x.

HAProxy Monitor on my local Plone 5.2.x Python 3 buildout / environment (only 2 of 4 instances are started by supervisor)

The next step would be a test with a copy of the database and content of the current LibreOffice extensions website. I asked for this some days ago, but got no answer yet.

Another Release Of TDF.Extensionuploadcenter

I added a new mail form to contact a project owner to the Plone add-on tdf.extensionuploadcenter yesterday. This new feature made it to the new release of this Plone add-on which I published on the Cheeseshop (https://pypi.org) today:
https://pypi.org/project/tdf.extensionuploadcenter/
It is published with the release number 0.49.

The source code of the add-on is available on Github:
https://github.com/andreasma/tdf.extensionuploadcenter

And here some screenshots of the new feature:

The section with the link to new project owner contact form
The new project owner contact form secured by recaptcha

This Plone add-on (former release) is driving the LibreOffice extensions website https://extensions.libreoffice.org. The new release of this add-on could be integrated into the website by running Buildout.