Computed Field on RichText

Just to add a detail: using ComputedAttribute on a RichText field results in a view error. Using the property decorator as @jaroel showed, worked for me in this situation. Edit: fails when adding a new piece of content.

I tried to debug the converter in plone.app.textfield.widget but was not successful.

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 162, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 371, in publish_module
  Module ZPublisher.WSGIPublisher, line 266, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 63, in call_object
  Module plone.z3cform.layout, line 63, in __call__
  Module plone.z3cform.layout, line 47, in update
  Module plone.dexterity.browser.edit, line 55, in update
  Module plone.z3cform.fieldsets.extensible, line 65, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 141, in update
  Module z3c.form.group, line 52, in update
  Module z3c.form.group, line 48, in updateWidgets
  Module z3c.form.field, line 277, in update
  Module plone.app.textfield.widget, line 42, in update
  Module z3c.form.browser.textarea, line 37, in update
  Module z3c.form.browser.widget, line 171, in update
  Module Products.CMFPlone.patches.z3c_form, line 47, in _wrapped
  Module z3c.form.widget, line 132, in update
  Module plone.app.textfield.widget, line 99, in toWidgetValue
ValueError: Can not convert <ComputedAttribute object at 0x7f4390e3c660> to an IRichTextValue

With the @property decorator adding new content results in:

Traceback (innermost last):
  Module ZPublisher.WSGIPublisher, line 162, in transaction_pubevents
  Module ZPublisher.WSGIPublisher, line 371, in publish_module
  Module ZPublisher.WSGIPublisher, line 266, in publish
  Module ZPublisher.mapply, line 85, in mapply
  Module ZPublisher.WSGIPublisher, line 63, in call_object
  Module plone.z3cform.layout, line 63, in __call__
  Module plone.z3cform.layout, line 47, in update
  Module plone.dexterity.browser.add, line 138, in update
  Module plone.z3cform.fieldsets.extensible, line 65, in update
  Module plone.z3cform.patch, line 30, in GroupForm_update
  Module z3c.form.group, line 145, in update
  Module plone.app.z3cform.csrf, line 22, in execute
  Module z3c.form.action, line 98, in execute
  Module z3c.form.button, line 315, in __call__
  Module z3c.form.button, line 170, in __call__
  Module plone.dexterity.browser.add, line 116, in handleAdd
  Module z3c.form.form, line 263, in createAndAdd
  Module plone.dexterity.browser.add, line 84, in create
  Module plone.dexterity.browser.add, line 198, in _applyChanges
  Module z3c.form.datamanager, line 91, in set
AttributeError: can't set attribute

What do you mean with ComputedAttribute on a RichText field?

I have a behavior with a RichText field that displays the backreferences to site editors. i.e. not stored on the content object.

The field is only displayed in edit mode (as a temporaty workaround) to mitigate my inability to display it in view mode in a separate tab, see this post: Tabbed view for default CT

@provider(IFormFieldProvider)
class IBackReferences(model.Schema):
    """ 
    """
    model.fieldset(
        'backreferences',
        label=_(u'Back References'),
        fields=[
            'backreferences'
        ]
    )

    backreferences = RichText(
        title=_(u'Back References'),
        description=_(u''),
        required=False,
        #readonly=True,
    )
    form.mode(IEditForm, backreferences='display')

and

@implementer(IBackReferences)
@adapter(IBackReferencesMarker)
class BackReferences(object):
    
    def __init__(self, context):
        self.context = context

    @property
    def backreferences(self):
        relationvalues = get_referers_list(self.context, True)
        brains = get_brains_for_relation_ids(self.context, relationvalues, sort_key='Title')
        html_result_list = ['<li><a href="%s">%s</a></li>' % (brain.getURL(), brain.Title) for brain in brains]
        return Markup(u'<ul>%s</ul>' % '\n'.join(html_result_list))

The edit view shows my backreferences for existing content. But editors can not add new content, plone fails with the second traceback.

If I use the @ComputedAttribute decorator on backreferences then content can be added but when the document is edited again, Plone fails with the first traceback.

I have other use cases where this approach does work. I just realize that there is no field named "image" in that behavior...

    @ComputedAttribute
    def image(self):
        image_link = getattr(self.context.aq_explicit, 'related_image', False)
        linked_image = image_link and self.context.related_image.to_object.image or ''
        return linked_image

Yeah, don't do that, it breaks :smiley:

If you want to go that route, please make sure you use a readonly TextLine (
Computed Field for Dexterity - #2 by jaroel) and a ComputedAttribute like Philip said in Computed Field for Dexterity - #7 by pbauer

Thanks :slight_smile: - the more I think about it the more I realize "that route" is a shortcut that I shouldn't have taken. If I want to add that extra tab in my behavior I should probably write a proper browserview and put my stuff in there.

1 Like

Plone Foundation Code of Conduct