[Zope-CMF] Solution: Point of Publication

Kevin Carlson khcarlso@bellsouth.net
Tue, 23 Apr 2002 15:51:42 -0400


Finally solved the problem of moving items from a member folder to a common
repository.  Before I get into the details, I would like to thank Dieter
Maurer and Florent Guillaume for their assistance in getting to a solution!

There are three steps involved in doing this.

1) Create a External script that will be run on a workflow transition
2) Create a default workflow based on DCWorkflow and select it as your new
default workflow
3) Customize the "content_status_modify" script in the portal_skins/content
folder.

Detail:
1) I created a script called MoveToRep in a module called
MoveToRepository.py that is stored in the Zope/Extensions directory.  The
script has the following content:

	def moveToRep(stateChange) :
		obj = stateChange.object
		portal=stateChange.getPortal()

		# dest is the destination that will receive the object when it is moved.
In this instance
		# portal.Repository is just a portal folder named "Repository".  Change
this to whatever
		# makes sense for you or better yet, create a property to hold this value.
		dest = portal.Repository
		parent=obj.aq_inner.aq_parent
		parent._delObject(obj.getId())
		newid = dest._setObject(obj.getId(), obj)
		newobj= dest._getOb(newid)
		raise stateChange.ObjectMoved(newobj, _redirect(newobj, "Moved"))


	from urllib import quote_plus

	def _redirect(obj, msg=None) :
		r = obj.REQUEST.RESPONSE
		url = '%s/view' % obj.absolute_url()
		if msg:
			url += '?FeedbackSuccessMessage=%s' % quote_plus(msg)
		r.redirect(url)


2) To create a new default workflow, the easiest thing to do is go to
portal_workflow/contents and click on Add New Workflow.  Select
default_workflow (Web-configurable workflow [Revision 2]).  Name it
something.  Rename the existing default_workflow to something different.
Rename the new workflow you just created to default_workflow.

After creating the new default workflow, select the workflow and then the
"Scripts" tab.  Add an external script with the following information:

	id: move
	Title:
	Module Name: MoveToRepository
	Function Name: MoveToRep

 Move back to the view of the new default workflow, select the "Transitions"
tab.  Select the transition that you want to drive the move operation.  (I
selected submit).  You'll see a select field for before-script and one for
after-script.  Select your external script from the drop down box.

You're almost done...

3) From the portal's root folder, select portal_skins.  From there select
'content'.  In the list of scripts, choose 'content_status_modify' and then
click on the Customize button.  Please note that at this point, you will be
modifying a skin which means you have to have the skin selected in order for
this last procedure to work.  If you move back to a script other than the
one you have customized, the move operation will not work.

Modify the content_status_modify script to look like this (notice that there
are several lines commented out and that's it):

context.portal_workflow.doActionFor(
    context,
    workflow_action,
    comment=comment)

#if workflow_action == 'reject':
#    redirect_url = context.portal_url() + '/search?review_state=pending'
#else:
#    redirect_url = '%s/view?%s' % ( context.absolute_url()
#                                  , 'portal_status_message=Status+changed.'
#                                  )

#context.REQUEST[ 'RESPONSE' ].redirect( redirect_url )



Your objects will now move when the workflow transition is hit.  This will
also adjust the catalog so the old instance of the object is removed and the
new, moved object is added.

Hope this helps everyone who has been looking for this type of
functionality!  Thanks again to Dieter and Florent!

Kevin