I'm looking for recommendations on how to store RichText in plone.app.registry
I've defined the following for a controlpanel:
# -*- coding: utf-8 -*-
from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper
from plone.app.registry.browser.controlpanel import RegistryEditForm
from plone.z3cform import layout
from plone.app.textfield import RichText
from zope import schema
from zope.interface import Interface
class IAnnouncementControlPanel(Interface):
site_announcement = RichText(
title=u'A announcement that shows on the website',
required=False,
)
show_on_all_pages = schema.Bool(
title=u'Show on All Pages',
description=u'Show on all pages not just the front page',
default=False,
required=False,
)
class AnnouncementControlPanelForm(RegistryEditForm):
schema = IAnnouncementControlPanel
schema_prefix = "site_announcement"
label = u'Announcement Settings'
AnnouncementControlPanelView = layout.wrap_form(
AnnouncementControlPanelForm, ControlPanelFormWrapper)
I thought it was as easy as defining a schema with RichText, but I get the following error:
Module plone.registry.registry, line 95, in registerInterface
TypeError: There is no persistent field equivalent for the field `site_announcement` of type `RichText`.
Use a Text field instead and assign a RichText widget to it. Maybe you need some data converters, if the default one doesn't adapt to the Text field or makes use of the RichTextValue object...
I went with this basically changing the default widget but still storing it as plain text:
from z3c.form.interfaces import INPUT_MODE
from z3c.form import form, field
from plone.app.z3cform.wysiwyg import WysiwygFieldWidget
....
class AnnouncementControlPanelForm(RegistryEditForm):
fields = field.Fields(IAnnouncementControlPanel)
fields['site_announcement'].widgetFactory[INPUT_MODE] = WysiwygFieldWidget
schema = IAnnouncementControlPanel
# this should give us a richtext widget for editing
schema_prefix = "site_announcement"
label = u'Announcement Settings'
it's not pretty clear to non-hardcore developers how to create a PersistentField as proposed in your answer; I checked the source but a pattern is not obvious.
here's an alternate solution for people using z3c.form based forms and plone.autoform instead:
from plone.app.z3cform.wysiwyg import WysiwygFieldWidget
from plone.autoform import directives as form
from plone.supermodel import model
from zope import schema
class IDisclaimerSettings(model.Schema):
...
form.widget('text', WysiwygFieldWidget)
text = schema.Text(
title=_(u'Body text'),
description=_(u'The text of the disclaimer.'),
required=True,
)
completely unrelated, but with theme fragments I (once) had a similar problem that I hacked around by using the rich text mockup pattern. You can set the class (klass="pat-tinymce") in the schema (but I am not sure if you can set other options)
from plone import api
from plone.autoform import directives as form
from plone.supermodel import model
from zope import schema
IS_PLONE_5 = api.env.plone_version().startswith('5')
class IDisclaimerSettings(model.Schema):
...
if IS_PLONE_5:
form.widget('text', klass='pat-tinymce')
else:
from plone.app.z3cform.wysiwyg import WysiwygFieldWidget
form.widget('text', WysiwygFieldWidget)
text = schema.Text(
title=_(u'Body text'),
description=_(u'The text of the disclaimer.'),
required=True,
)
widget('program_view_footer', klass='pat-tinymce' ) # works for Plone 5.x
# widget(program_view_footer=WysiwygFieldWidget) # results in deprecation warnings but works ok in Plone 5.0
program_view_footer = schema.Text(
title=_(u'Program Footer Text'),
description=_(u'will appear at bottom of public program view'),
required=False,
missing_value=None,
default=None,
)