ploneplone-5.x

HTTP redirect after check in event


I am using Plone 5.0 with the plone.app.iterate addon for the checkout option and an intranet/extranet workflow. To fuse these two concepts my idea is: After every workflow transition an event handler checks, whether the page is a working copy and if it is a published page. If so the page automatically should be checked in. So after the review of a working copy it is checked in. In order to accomplish this I wrote the following event handler:

from Acquisition import aq_inner
from plone import api
from plone.app.iterate.interfaces import IWorkingCopy, ICheckinCheckoutPolicy
from plone.app.iterate import PloneMessageFactory as _
from Products.CMFCore.utils import getToolByName
from Products.statusmessages.interfaces import IStatusMessage

def checkInIfNeeded(document, event):
    context = aq_inner(document)
    workflowTool = getToolByName(context, "portal_workflow")
    status = workflowTool.getStatusOf("intranet_workflow", document)
    if IWorkingCopy.providedBy(context) and status["review_state"] == "internally_published":
       policy = ICheckinCheckoutPolicy(context)
       baseline = policy.checkin("")
       IStatusMessage(context.REQUEST).addStatusMessage(
        _("Checked in"), type='info')
       view_url = baseline.restrictedTraverse("@@plone_context_state").view_url()
       context.request.response.redirect(view_url)

The code for the check in is pretty much from the source of the interface This works fine until the last line where the user triggering the event should be redirected to the now checked in main branch of the page. The user is redirected to a page of the working copy, (which now no longer exists), telling the user the page is unavailable. What did I do wrong?


Solution

  • Pure redirect call are not working everywhere because other redirect can be called later (they never works in event handlers).

    Try to add this:

    from zExceptions import Redirect
    

    and change the last line with:

    raise Redirect(view_url)
    

    I'm unsure if you must also add a transaction.commit() from transaction module before the redirect call.