We needed some more complex Registry settings and an associated Control Panel form for a plug-in we are working on for Plone. In a recent article the Red Turtle guys showed us how use complex schemas to auto create forms and store the results in the registry which worked great. Unfortunately the technique, as they point out, defeats one of the goals of the registry to allow the values to be edited with just the normal registry control panel. So we were inspired to develop something to turn complex schemas into something that allowed us to store our registry settings in a human readable way.
For example take schema with a list in it:
class IFacetDefinition(Interface):
name = schema.ASCIILine(title=_(u"Facet Name"), required=True)
description = schema.ASCIILine(title=_(u"Description"), required=False)
class IFacetSettings (Interface):
facets = schema.Tuple(
title=_(u'Additional Facet Fields'),
description=(u"Names of additional keyword fields"),
value_type=schema.Object(IFacetDefinition, title=_(u"Facet Definition")),
required=False,
default=(),
missing_value=()
)
We won't use the registry.xml generic setup profile step to register this schema as it will complain.
Instead we created a new registry proxy that deals with setting and getting attributes of schemas which are lists.
reg = getUtility(IRegistry)
proxy = ComplexRecordsProxy(reg, IFacetSettings, prefix='collective.facets')
You can now use "proxy.facets" as you would any list. e.g.
print [f.name for f in proxy.facets]
del proxy.facets[5]
The results would be stored in the registry like this
collective facets facets/i00000 description | Description | ASCIILine | blah | |
collective facets facets/i00000 name | Facet Name | ASCIILine | blah | |
collective facets facets/i00001 description | Description | ASCIILine | A long description | |
collective facets facets/i00001 name | Facet Name | ASCIILine | My Facet |
Yes this schema won't work for 100000 items but I'm not sure you should be using the registry for a list that long anyway :)
The proxy makes it easy to create a control panel form for our settings schema
class FacetSettingsEditForm (controlpanel.RegistryEditForm):
schema = IFacetSettings
label = u"Facets Settings"
description = u"Manage your additional facets"
def getContent(self):
reg = getUtility(IRegistry)
return ComplexRecordsProxy(reg, IFacetSettings, prefix='collective.facets')
def applyChanges(self, data):
reg = getUtility(IRegistry)
proxy = ComplexRecordsProxy(reg, IFacetSettings, prefix='collective.facets')
proxy.facets = data['facets']
...
Neat. Nice control panel, nicely stored.