In registry.xml: no way to remove element from collection on import

If I am correct in reading plone.supermodel.utils.elementToValue (used by plone.app.registry import of registry.xml), there's no way to specify deletion/removal of a specific collection element. This is a bummer, as it means there's no declarative way in policy/profile to remove items from plone.displayed_types (I don't want file, image in displayed_types, nor do I want to enumerate every single type).

What have folks used to work around? I am reluctantly (and with some grumbling) reaching for a programmatic import step via plone.api.portal.set_registry_record, not sure what else to do.

I'm happy to hack plone.supermodel to give it element purge features for collection import, but I'm wary of breaking any other downstream consumers (outside of plone.supermodel and plone.app.registry).

Sean

1 Like

GenericSetup has a standard way to remove objects. Ideally, Plone should use this way. If it does not (yet), it should get changed to do it.

I'm happy to hack plone.supermodel to give it element purge features for collection import, but I'm wary of breaking any other downstream consumers (outside of plone.supermodel and plone.app.registry).

This is an entirely reasonable feature request. plone.app.registry's import handler already handles the purge attribute on a value tag to control whether the list is cleared before importing. I think what you're looking for is remove="true" on a particular element. I think I would approach this by making elementToValue return a sentinel value if the tag has remove="true". Downstream consumers can then do what they want with that. There shouldn't be a backwards-compatibility problem since we're adding support for a new attribute, not changing how an existing one is handled.

What have folks used to work around? I am reluctantly (and with some grumbling) reaching for a programmatic import step via plone.api.portal.set_registry_record, not sure what else to do.

Unfortunately, we're using this approach as well.

If you're using Products.GenericSetup >= 1.8.2 and don't want to create an importStep and a setuphandlers.py just for this, you can use the new post_handler attribute when registering your profile to call a function in your package that does the removal. This is specially useful if you already have a python module somewhere in your package for uninstalling.

I'm just hitting the same issue with a Dict field.
I want to remove a value by key via registry file.
Is this posible now or still missing feature?
What can we do to implement it, the whole supermodel looks like magic for me and not much docs are out there.

Not sure if this is what you intend to do:

<records remove='true' interface='my_theme.interfaces.IMySchema' />

<!-- alternatively, remove each record separately -->
       
<record remove='true' name='my_theme.interfaces.IMySchema.MyDictField' />


no not really, thats all on record level, i want to remove value-elements inside a dict-record ;).
Thats what i would expect to work in xml. But i have no clue how to implement it in supermodel.
And currently i just don't have the time to stop working for a coulple of days to dig into that, to figure out how things are working inside supermodel/generic-setup.

As far as I can remember, the purge attribute works there.

<?xml version="1.0"?>
<registry>
  <records prefix="plone.app.mosaic.app_tiles.custom_tiles_content_summary"
           interface="plone.app.mosaic.interfaces.ITile">
    <value purge="True" key="name" />
    <value purge="True" key="label" />
  </records>
</registry>

Also see here, apparently an upgrade step was needed to iterate over all records in the interface and delete:

Aw snap! I'm running into this now (and finally understand what you mean). Removing an individual element, e.g. like

  <record name="plone.allowed_sizes" interface="Products.CMFPlone.interfaces.controlpanel.IImagingSchema" field="allowed_sizes">
    <value purge="false">
      <element>slider_full_height 1900:1080</element>
      <element>slider_half_height 1900:540</element>
      <element>slider_quarter_height 1900:270</element>
    </value>
  </record>

does not seem to be possible...

1 Like
 <record name="plone.allowed_sizes" interface="Products.CMFPlone.interfaces.controlpanel.IImagingSchema" field="allowed_sizes">
<value purge="false">
  <element>slider_full_height 1900:1080</element>
  <element>slider_half_height 1900:540</element>
  <element>slider_quarter_height 1900:270</element>
</value>

will keep all the current image sizes and add 3 more.

 <record name="plone.allowed_sizes" interface="Products.CMFPlone.interfaces.controlpanel.IImagingSchema" field="allowed_sizes">
<value purge="True">
  <element>slider_full_height 1900:1080</element>
  <element>slider_half_height 1900:540</element>
  <element>slider_quarter_height 1900:270</element>
</value>

Will remove all current image sizes and add 3. So after import you will only have 3 sizes.

Did you try with:

 remove="true"

I can not remember if that can be used on an element

Yes, you are correct. The code I inserted would add my new image sizes, with no clean way to remove them. This is because the record values (and their elements), that is: inside the field element, use plone.supermodel syntax.

Upthread, @davisagli mentioned he intended t olook into adding a feature to purge elements.

Plone Foundation Code of Conduct