Add new entry to plone.registry without restarting GenericSetup / reinstalling product

in the Plone add-on product, I have a control panel page on which some configuration parameters can be set. They are stored in plone.registry. The control panel adapter retrieves the various fields in its __init__ method, requesting an interface, for example:

 class MultiLanguageExtraOptionsAdapter(LanguageControlPanelAdapter): implementsOnly(IMultiLanguageExtraOptionsSchema) def __init__(self, context): super(MultiLanguageExtraOptionsAdapter, self).__init__(context) self.registry = getUtility(IRegistry) self.settings = self.registry.forInterface( IMultiLanguageExtraOptionsSchema) 

Now I add an extra field to the IMultiLanguageExtraOptionsSchema interface and restart plone. An error appears on the control panel page:

 KeyError: 'Interface `plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema` defines a field `blah`, for which there is no record.' 

(This is expected for the forInterface method, as described in plone.registry README. No entry).

Of course, if I add this field through GenericSetup (registry.xml), and I reinstall the product / rerun the "Control Panel" step, everything is fine:

 <registry> <records interface="plone.app.multilingual.interfaces.IMultiLanguageExtraOptionsSchema"> <value key="blah"></value> <records> <registry> 

But I do not want to force users to reinstall the product, simply because there is a new option in the product-specific control panel. So my question is: is there a recommended way to get a new record for a new field in plone.registry?

+4
source share
3 answers

If you pass False as the second forInterface parameter:

 registry.forInterface(IMultiLanguageExtraOptionsSchema, False) 

then it does not throw an error if the fields from the schema are not in the registry, but simply return the default value for the field.

+4
source

You can try / catch KeyError and then make sure all registry settings are registered:

 try: self.settings = self.registry.forInterface(IMultiLanguageExtraOptionsSchema) except KeyError: registry = getUtility(IRegistry) registry.registerInterface(IMultiLanguageExtraOptionsSchema) 

I would recommend writing an update step (which would force your users to reinstall the product, of course).

upgrades.py:

 def update_registry(context): registry = getUtility(IRegistry) registry.registerInterface(IMultiLanguageExtraOptionsSchema) 

upgrades.zcml ::

  <genericsetup:upgradeStep source="*" destination="1100" title="Update plone.app.multilingual setting registry" description="" profile="plone.app.multilingual:default" handler=".upgrades.update_registry" /> 

Cm

https://github.com/collective/collective.mailchimp/blob/master/collective/mailchimp/upgrades.py

and

https://github.com/collective/collective.mailchimp/blob/master/collective/mailchimp/upgrades.zcml

for example.

+7
source

Safe retrieval of settings from the registry:

 def get_registry_settings(interface, name): registry = getUtility(IRegistry) settings = registry.forInterface(interface, check=False) value = getattr(settings, name) if value == settings.__schema__[name].missing_value: value = settings.__schema__[name].default return value 
+2
source

Source: https://habr.com/ru/post/1468760/


All Articles