Moving behavior fields to different fieldset?

I have a custom DX content-types and collective.geolocationbehavior added to the CT through its FTI.

Now the geolocation field shows up default fieldset in edit mode. I need to move it to a different fieldset or its own fieldset.

Using this

fieldset('MyField', fields=['geolocation'])

inside my schema does work:

zope.configuration.config.ConfigurationExecutionError: <type 'exceptions.ValueError'>: The directive plone.supermodel.fieldsets applied to interface dynamore.policy.content.dynalocation.IDynalocation refers to unknown field name geolocation
  in:
  File "/home/ajung/sandboxes/plone-server-buildout-plone5/eggs/plone.supermodel-1.3.4-py2.7.egg/plone/supermodel/configure.zcml", line 9.4-12.10
      <zcml:customAction
          handler=".model.finalizeSchemas"
          order="9999999"
          />

You can do this globally by moving the fields for all CTs using it (example showing the changeNote field, but can be applied to all other behaviors as well):

from plone.app.dexterity import _ as _DX
from plone.app.versioningbehavior.behaviors import IVersionable
from plone.supermodel.interfaces import FIELDSETS_KEY
from plone.supermodel.model import Fieldset


settings = Fieldset(
    'settings',
    label=_DX(u'Settings'),
    fields=['changeNote'],
)
fieldsets = IVersionable.getTaggedValue(FIELDSETS_KEY)
fieldsets.append(settings)
1 Like

Your (magic) example code works great! I initially thought it belonged in the class definition for the content type's interface but, in fact, it belongs outside of any class definition.

But I could not get it to work with lead image behaviour. It would result in this error. I don't know why ILeadImage would be different.

KeyError: 'Plone.supermodel.fieldsets'

when reaching the line

fieldsets = ILeadImage.getTaggedValue(FIELDSETS_KEY)

The way I found that worked was to override the two lead image classes with my own behaviours.py file:

# -*- coding: utf-8 -*-
from plone.app.contenttypes import _
from plone.autoform.interfaces import IFormFieldProvider
from plone.app.contenttypes.behaviors.leadimage import ILeadImage
from plone.dexterity.interfaces import IDexterityContent
from plone.supermodel import model
from zope.component import adapter
from zope.interface import implementer
from zope.interface import provider


@provider(IFormFieldProvider)
class IOIELeadImage(ILeadImage):
    model.fieldset(
        'leadimage',
        label=_(u'Lead Image'),
        fields=['image', 'image_caption'],
    )


@implementer(IOIELeadImage)
@adapter(IDexterityContent)
class LeadImage(object):

    def __init__(self, context):
        self.context = context

and then using that behaviour in the content type XML definition instead.

...ok maybe I spoke too soon...it behaves correctly in the add form but isn't working when saving

[a moment passes]
To go down this route and have it work, I had to register my new customized behaviour.

But @tmassman's (much simpler and more elegant) original suggestion works for lead images if you do something like this:

leadimage_fieldset = Fieldset(
    'leadimage',
    label=_(u'Lead Image'),
    fields=['image', 'image_caption'],
)
try:
    leadimage_fieldsets = ILeadImage.getTaggedValue(FIELDSETS_KEY)
    leadimage_fieldsets.append(leadimage_fieldset)
except KeyError:
    ILeadImage.setTaggedValue(FIELDSETS_KEY, [leadimage_fieldset])

I know ILeadImage defines no fieldsets because calling ILeadImage.getTaggedValue(FIELDSETS_KEY) gives a KeyError. I used a try block to be more general here.

This should be added to the docs...https://github.com/plone/plone.app.dexterity/issues/282 and https://github.com/plone/training/issues/379

Plone Foundation Code of Conduct