Requiring a comment for certain workflow changes


Plone 6 Classic.

During user started WF transitions i want to control if a comment form is displayed to the user and define if required to allow the transition taking effect.

For example, if i am submitting content for review (in my example) no comment would be required or available.

However, let's say you were rejecting something assigned to you and you want to transition "reject" (for example) then i would want a note/comment to be required.

I know if i go to transition and select "advanced" towards the bottom i see the option of a note. so that is the start. I want this comment box to be displayed (outside of the "Advanced" option) when it is required.
also, i want to set this as a requirement in the transition in my workflow


You can perform this by creating a form or a view "reject_comment" BrowserView for your layer, setting field as required.

class RejectCommentView(BrowserView):
    """Handles the workflow reject_comment transition of objects.

    Former Controller Python Script "content_status_modify".

    validators = validate_content_status_modify


    index = ViewPageTemplateFile('templates/')
    workflow_action = 'rechazar'

    def label(self):
        return _('heading_reject_process', default="Reject process")

    def __call__(
        """Do a workflow reject action.

        Also, when the view is called on a default page,
        the code below tries to do the same transition on the parent folder,
        by calling this view on the parent.  This may easily fail.
        This is yet another reason to be lenient.
        Otherwise you may see both a successful portal status message
        and one with an error.
        In the form you can also add a comment.
        form = self.request.form
        context = aq_inner(self.context)
        portal_workflow = getToolByName(context, "portal_workflow")
        self.plone_utils = getToolByName(context, "plone_utils")

        if form.get('form.button.Cancel'):
            IStatusMessage(self.request).add(_("Changes cancelled."))
            return self.request.response.redirect(context.absolute_url())

        if form.get('form.submitted'):
            # If a workflow action was specified, there must be a plone.protect authenticator.

            # Validate if comment....
            if not comment:
                # do something here...

            # Make sure an effective date is always set when there is a valid workflow action.
            transitions = portal_workflow.getTransitionsFor(context)
            transition_ids = [t["id"] for t in transitions]

            # Create the note while we still have access to the original context
            note = "Changed status of {} at {}".format(

            if self.workflow_action in transition_ids:
                # The action could result in a move or delete.
                # In that case we get a new context as answer.
                context = portal_workflow.doActionFor(
                    context, self.workflow_action, comment=comment
                if context is None:
                    # the normal case
                    context = aq_inner(self.context)


            # If this item is the default page in its parent, attempt to publish that
            # too. It may not be possible, of course
            parent = aq_parent(context)
            if is_default_page(parent, context):
                    parent_modify_view = getMultiAdapter(
                        (parent, self.request), name="reject_comment"
                except ConflictError:
                except Exception:

            IStatusMessage(self.request).add(_("Item state changed."))
            return self.request.response.redirect(context.absolute_url())

        return self.index()

Then apply the URL to the reject action:

<action url="%(content_url)s/reject_comment" category="workflow" icon="">Reject</action>

And each time a reject transition is executed the form/view will be rendered.

@rber474 thanks a lot. I'll pass this on to the programmer working on this issue.