[Zope3-checkins] CVS: Zope3/src/zope/app/browser/workflow/stateful - __init__.py:1.1 add.pt:1.1 addstate.pt:1.1 addtransition.pt:1.1 configure.zcml:1.1 content_filter.py:1.1 contentworkflow.py:1.1 contentworkflow_index.pt:1.1 definition.py:1.1 definition_index.pt:1.1 definition_states.pt:1.1 definition_transitions.pt:1.1 filterTest.pt:1.1 filteradapter.py:1.1 instance.py:1.1 instance_manage.pt:1.1 interfaces.py:1.1 published_content.pt:1.1
Ulrich Eck
ueck@net-labs.de
Thu, 8 May 2003 13:27:19 -0400
Update of /cvs-repository/Zope3/src/zope/app/browser/workflow/stateful
In directory cvs.zope.org:/tmp/cvs-serv7538/src/zope/app/browser/workflow/stateful
Added Files:
__init__.py add.pt addstate.pt addtransition.pt configure.zcml
content_filter.py contentworkflow.py contentworkflow_index.pt
definition.py definition_index.pt definition_states.pt
definition_transitions.pt filterTest.pt filteradapter.py
instance.py instance_manage.pt interfaces.py
published_content.pt
Log Message:
Finally got it into Zope3:
Workflow has arrived!
this is a merge of the workflow package that was seperatly developed
at /Packages3/workflow.
please to a
cvs update -dPA
to ensure that old files/directories are deleted, otherwise you'll
probably encounter errors when trying to run zope3
if you have problems .. send me an email ueck <at> net-labs.de
Ulrich
=== Added File Zope3/src/zope/app/browser/workflow/stateful/__init__.py ===
=== Added File Zope3/src/zope/app/browser/workflow/stateful/add.pt ===
<html metal:use-macro="views/standard_macros/dialog">
<body>
<div metal:fill-slot="body">
<form action="action.html" method="POST">
<table class="TypeListing" cellpadding="3">
<caption>Add Content</caption>
<tbody tal:repeat="info view/addingInfo">
<tr>
<td class="Selector">
<input type="radio" name="type_name"
tal:attributes="value info/action; id info/action" />
</td>
<td class="TypeName">
<label style="font-weight: bold;"
tal:attributes="for info/action">
<span tal:replace="info/title" >Folder</span>
</label>
<div class="TypeDescription" tal:content="info/description">
Folders are generic containers for content, including other
folders.
</div>
</td>
</tr>
</tbody>
<tbody tal:condition="nothing">
<tr>
<td class="Selector">
<input type="radio" name="type_name" value="" />
</td>
<td class="TypeName">
<img alt="Folder" src="../../ZMI/www/document_icon.gif" />
Document
</td>
</tr>
<tr>
<td class="Selector"><br /></td>
<td class="TypeDescription">
Documents are simple textual content.
</td>
</tr>
</tbody>
<tr>
<td><br/></td>
<td>
<input type="text" name="id"
tal:condition="view/namesAccepted"
tal:attributes="value request/id | nothing"
/>
<input type="submit" value=" Add " />
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/addstate.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title>Add State</title>
</head>
<body>
<div metal:fill-slot="body">
<form action="." method="post" enctype="multipart/form-data">
<table>
<tbody>
<tr>
<th>Id:</th>
<td>
<input type="text" name="id" size="40" value="">
</td>
</tr>
</tbody>
</table>
<input type="submit" name="action.html:method" value="Add" />
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/addtransition.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title>Add Transition</title>
</head>
<body>
<div metal:fill-slot="body">
<form action="." method="post" enctype="multipart/form-data">
<table>
<tbody tal:define="states view/getStateNames">
<tr>
<th>Id:</th>
<td>
<input type="text" name="id" size="40" value="">
</td>
</tr>
<tr>
<th>Source State:</th>
<td>
<select name="source">
<option tal:repeat="state states"
tal:content="state" />
</select>
</td>
</tr>
<tr>
<th>Destination State:</th>
<td>
<select name="destination">
<option tal:repeat="state states"
tal:content="state" />
</select>
</td>
</tr>
<tr>
<th>Condition:</th>
<td>
<input type="text" name="condition" size="40" value="">
</td>
</tr>
<tr>
<th>Permission:</th>
<td>
<input type="text" name="permission" size="40" value="">
</td>
</tr>
</tbody>
</table>
<input type="submit" name="action.html:method" value="Add" />
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/configure.zcml ===
<zopeConfigure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser">
<!-- Stateful Workflow Process Definition -->
<browser:menuItem
menu="add_component"
for="zope.app.interfaces.container.IAdding"
action="StatefulProcessDefinition"
title="Stateful Process Definition"
description="A stateful workflow process definition" />
<browser:pages
for="zope.app.interfaces.workflow.stateful.IStatefulProcessDefinition"
class="zope.app.browser.workflow.stateful.definition.StatefulProcessDefinitionView"
permission="zope.ManageServices">
<browser:page name="index.html" template="definition_index.pt" />
</browser:pages>
<browser:editform
schema="zope.app.interfaces.workflow.stateful.IStatefulProcessDefinition"
name="edit.html"
menu="zmi_views"
label="Edit a Stateful ProcessDefinition"
permission="zope.workflow.ManageProcessDefinitions"
/>
<browser:menuItems
for="zope.app.interfaces.workflow.stateful.IStatefulProcessDefinition"
menu="zmi_actions">
<browser:menuItem title="Manage States" action="states/contents.html" />
<browser:menuItem title="Manage Transitions" action="transitions/contents.html" />
</browser:menuItems>
<!-- States/Transitions Container Adding Menus -->
<browser:menu id="add_stateful_states" title="State Items" />
<browser:menu id="add_stateful_transitions" title="Transition Items" />
<!-- States Container -->
<browser:view
for="zope.app.interfaces.workflow.stateful.IStatefulStatesContainer"
name="+"
menu="zmi_actions" title="Add"
class=".definition.StatesContainerAdding"
permission="zope.workflow.ManageProcessDefinitions"
allowed_attributes="addingInfo"
>
<browser:page name="index.html" template="add.pt" />
<browser:page name="action.html" attribute="action" />
</browser:view>
<!-- State -->
<!-- nothing to edit yet
<browser:editform
schema="zope.app.interfaces.workflow.stateful.IState"
name="edit.html"
menu="zmi_views"
label="Edit a State"
permission="zope.workflow.ManageProcessDefinitions"
/>
-->
<browser:addform
name="AddState"
menu="add_stateful_states" title="Stateful State"
schema="zope.app.interfaces.workflow.stateful.IState"
class=".definition.StateAddFormHelper"
permission="zope.workflow.ManageProcessDefinitions"
content_factory="zope.app.workflow.stateful.definition.State"
arguments=""
fields=""
/>
<!-- Transitions Container -->
<browser:view
for="zope.app.interfaces.workflow.stateful.IStatefulTransitionsContainer"
name="+"
menu="zmi_actions" title="Add"
class=".definition.TransitionsContainerAdding"
permission="zope.workflow.ManageProcessDefinitions"
allowed_attributes="addingInfo"
>
<browser:page name="index.html" template="add.pt" />
<browser:page name="action.html" attribute="action" />
</browser:view>
<!-- Transition -->
<browser:editform
schema="zope.app.interfaces.workflow.stateful.ITransition"
name="edit.html"
menu="zmi_views"
label="Edit a Transition"
permission="zope.workflow.ManageProcessDefinitions"
/>
<browser:addform
name="AddTransition"
menu="add_stateful_transitions" title="Stateful Transition"
schema="zope.app.interfaces.workflow.stateful.ITransition"
permission="zope.workflow.ManageProcessDefinitions"
content_factory="zope.app.workflow.stateful.definition.Transition"
arguments="sourceState destinationState condition script permission triggerMode"
fields="sourceState destinationState condition script permission triggerMode"
/>
<!-- ContentWorkflowsUtility -->
<browser:menuItem
menu="add_component"
for="zope.app.interfaces.container.IAdding"
action="ContentWorkflowsUtility"
title="Content Workflows Utility"
description="An utility for creating/deleting workflow for content objects." />
<browser:pages
for="zope.app.interfaces.workflow.stateful.IContentWorkflowsUtility"
class="zope.app.browser.workflow.stateful.contentworkflow.ContentWorkflowsUtilityView"
permission="zope.ManageServices">
<browser:page name="index.html" template="contentworkflow_index.pt" />
</browser:pages>
<browser:menuItem
menu="zmi_views"
for="zope.app.interfaces.workflow.stateful.IContentWorkflowsUtility"
action="index.html"
title="Overview"
description="ContentWorkflowsUtility Overview" />
<!-- ProcessInstanceContainerAdaptable -->
<browser:pages
for="zope.app.interfaces.workflow.IProcessInstanceContainerAdaptable"
permission="zope.workflow.UseProcessInstances"
class="zope.app.browser.workflow.stateful.instance.ManagementView">
<browser:page name="workflows.html" attribute="contents" />
<browser:page name="fireTransition.html" attribute="fireTransition" />
</browser:pages>
<browser:menuItem
for="zope.app.interfaces.workflow.IProcessInstanceContainerAdaptable"
menu="zmi_views"
title="Workflows"
action="workflows.html"
/>
<browser:pages
for="zope.app.interfaces.container.IContentContainer"
permission="zope.View"
class="zope.app.browser.workflow.stateful.content_filter.FilterList">
<browser:page name="published_content.html" attribute="published_content" />
</browser:pages>
<!-- uhm .. this seems to be to generic in its definition
and not really nice as well .. -->
<adapter
factory=".filteradapter.FilterAdapter"
provides=".interfaces.IContentFilterAdapter"
for="zope.app.interfaces.annotation.IAttributeAnnotatable"
permission="zope.View" /> <!-- XXX is this permission right? -->
</zopeConfigure>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/content_filter.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""filtering view for ProcessInstances of a stateful workflow
$Id: content_filter.py,v 1.1 2003/05/08 17:27:17 jack-e Exp $
"""
__metaclass__ = type
from zope.component import getAdapter, queryAdapter, getService
from zope.app.services.servicenames import Workflows
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.app.interfaces.workflow import IProcessInstanceContainerAdaptable
from zope.app.interfaces.workflow import IProcessInstanceContainer
from zope.app.interfaces.workflow.stateful import IStatefulProcessInstance
from zope.app.browser.container.contents import Contents
class FilterList(Contents):
__used_for__ = IProcessInstanceContainerAdaptable
def filterByState(self, objList, state, workflow='default'):
"""Filter a list of objects according to given workflow and state
objList ... list of objects
state ... name of a state (of the given workflow) in which the result
objects must be
workflow ... name of a workflow to which result objects must be attached
"""
res = []
for obj in objList:
adapter = queryAdapter(obj['object'], IProcessInstanceContainer)
if adapter:
for item in adapter.values():
if item.processDefinitionName != workflow:
continue
if item.status == state:
res.append(obj)
break
return res
published_content = ViewPageTemplateFile('published_content.pt')
def listPublishedItems(self):
return self.filterByState(self.listContentInfo(), 'published')
=== Added File Zope3/src/zope/app/browser/workflow/stateful/contentworkflow.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ContentWorkflow Utility views
$Id: contentworkflow.py,v 1.1 2003/05/08 17:27:17 jack-e Exp $
"""
__metaclass__ = type
from zope.component import getServiceManager
from zope.publisher.browser import BrowserView
from zope.app.form.utility import setUpWidgets, getWidgetsDataForContent
from zope.app.interfaces.workflow.stateful import IContentWorkflowsUtility
class ContentWorkflowsUtilityView(BrowserView):
def getName(self):
return """I'm a ContentWorkflows Utility"""
=== Added File Zope3/src/zope/app/browser/workflow/stateful/contentworkflow_index.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title>Registration "Service" Control Page</title>
</head>
<body>
<div metal:fill-slot="body">
<h1>Subscription control</h1>
<span tal:condition="request/callSubscribe|nothing" tal:omit-tag="">
<span tal:define="dummy context/subscribe" tal:omit-tag=""/>
</span>
<span tal:condition="request/callUnsubscribe|nothing" tal:omit-tag="">
<span tal:define="dummy context/unsubscribe" tal:omit-tag=""/>
</span>
<form method="POST">
<span tal:condition="context/isSubscribed" tal:omit-tag="">
Subscription state: ON
<input type="submit" value="Unsubscribe" name="callUnsubscribe" />
</span>
<span tal:condition="not:context/isSubscribed" tal:omit-tag="">
Subscription state: OFF
<input type="submit" value="Subscribe" name="callSubscribe" />
</span>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/definition.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ProcessDefinition configuration adding view
$Id: definition.py,v 1.1 2003/05/08 17:27:17 jack-e Exp $
"""
__metaclass__ = type
from zope.proxy.introspection import removeAllProxies
from zope.component import getServiceManager
from zope.publisher.browser import BrowserView
from zope.app.browser.container.adding import Adding
from zope.app.form.utility import setUpWidgets, getWidgetsDataForContent
from zope.app.interfaces.workflow.stateful import IStatefulProcessDefinition
from zope.app.workflow.stateful.definition import State, Transition
from zope.app.browser.form.submit import Update
class StatesContainerAdding(Adding):
"""Custom adding view for StatesContainer objects.
"""
menu_id = "add_stateful_states"
class TransitionsContainerAdding(Adding):
"""Custom adding view for TransitionsContainer objects.
"""
menu_id = "add_stateful_transitions"
def getProcessDefinition(self):
return self.context.getProcessDefinition()
# XXX Temporary ...
class StateAddFormHelper:
# XXX Hack to prevent from displaying an empty addform
def __call__(self, template_usage=u'', *args, **kw):
if not len(self.fieldNames):
self.request.form[Update] = 'submitted'
return self.update()
return super(StateAddFormHelper, self).__call__(template_usage, *args, **kw)
class StatefulProcessDefinitionView(BrowserView):
def getName(self):
return """I'm a stateful ProcessInstance"""
class AddState(BrowserView):
def action(self, id):
state = State()
self.context.setObject(id, state)
return self.request.response.redirect(self.request.URL[-2])
class AddTransition(BrowserView):
def getStateNames(self):
pd = self.context.getProcessDefinition()
states = removeAllProxies(pd.getStateNames())
states.sort()
return states
def action(self, id, source, destination, condition=None, permission=None):
condition = condition or None
permission = permission or None
transition = Transition(source, destination, condition, permission)
self.context.setObject(id, transition)
return self.request.response.redirect(self.request.URL[-2])
=== Added File Zope3/src/zope/app/browser/workflow/stateful/definition_index.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title>ProcessDefinition</title>
</head>
<body>
<div metal:fill-slot="body">
<p>ProcessDefinition: <tal:block tal:replace="view/getName" /></p>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/definition_states.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title>ProcessDefinition States</title>
</head>
<body>
<div metal:fill-slot="body">
states
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/definition_transitions.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<title>ProcessDefinition Transitions</title>
</head>
<body>
<div metal:fill-slot="body">
transitions
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/filterTest.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css"></style>
</head>
<body>
<div metal:fill-slot="body">
<div tal:repeat="obj view/filterTest"
tal:omit-tag="">
<div tal:replace="obj"/><br/>
</div>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/filteradapter.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""filtering view for ProcessInstances of a stateful workflow
$Id: filteradapter.py,v 1.1 2003/05/08 17:27:17 jack-e Exp $
"""
__metaclass__ = type
from zope.component import queryAdapter
from zope.app.interfaces.workflow import IProcessInstanceContainerAdaptable
from zope.app.interfaces.workflow import IProcessInstanceContainer
from interfaces import IContentFilterAdapter
class FilterAdapter:
__used_for__ = IProcessInstanceContainerAdaptable
__implements__ = IContentFilterAdapter
def __init__(self, context):
self.context = context
def filterListByState(self, objList, state, workflow='default'):
"""See IContentFilterAdapter"""
res = []
for obj in objList:
if self.filterObjectByState(obj, state, workflow):
res.append(obj)
return res
def filterObjectByState(self, object, state, workflow='default'):
"""See IContentFilterAdapter"""
adapter = queryAdapter(object, IProcessInstanceContainer)
if not adapter:
return False
for item in adapter.values():
if item.processDefinitionName != workflow:
continue
if item.status == state:
return True
return False
=== Added File Zope3/src/zope/app/browser/workflow/stateful/instance.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""ProcessInstance views for a stateful workflow
$Id: instance.py,v 1.1 2003/05/08 17:27:17 jack-e Exp $
"""
__metaclass__ = type
from zope.schema import getFieldNames
from zope.component import queryView, queryAdapter, getAdapter, getService
from zope.app.services.servicenames import Workflows
from zope.publisher.browser import BrowserView
from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile
from zope.app.interfaces.workflow import IProcessInstanceContainerAdaptable
from zope.app.interfaces.workflow import IProcessInstanceContainer
from zope.app.interfaces.workflow.stateful import IStatefulProcessInstance
from zope.app.interfaces.dublincore import IZopeDublinCore
from zope.proxy.introspection import removeAllProxies
from zope.proxy.context import getWrapperData
class ManagementView(BrowserView):
__used_for__ = IProcessInstanceContainerAdaptable
def _extractContentInfo(self, item):
id, processInstance = item
info = {}
info['id'] = id
info['name']=self._getTitle(self._getProcessDefinition(processInstance))
return info
def listContentInfo(self):
return map(self._extractContentInfo,
getAdapter(self.context, IProcessInstanceContainer).items())
contents = ViewPageTemplateFile('instance_manage.pt')
contentsMacros = contents
def getWorkflowTitle(self):
pi = self._getSelWorkflow()
if pi is None:
return None
return self._getTitle(self._getProcessDefinition(pi))
def getTransitions(self):
info = {}
pi = self._getSelWorkflow()
if pi is None:
return info
pd = self._getProcessDefinition(pi)
clean_pd = removeAllProxies(pd)
current_state = clean_pd.getState(pi.status)
adapter = getAdapter(current_state, IZopeDublinCore)
info['status'] = adapter.title or pi.status
transition_names = pi.getOutgoingTransitions()
trans_info = []
for name in transition_names:
transition = clean_pd.getTransition(name)
adapter = getAdapter(transition, IZopeDublinCore)
trans_info.append({'name':name,
'title': adapter.title or name})
info['transitions'] = trans_info
return info
def fireTransition(self):
pi = self._getSelWorkflow()
if pi is None:
return
trans = self.request.get('selTransition', None)
self.request.response.redirect('@@workflows.html?workflow=%s' % pi.processDefinitionName)
if pi and trans:
pi.fireTransition(trans)
def _getTitle(self, obj):
return getAdapter(obj, IZopeDublinCore).title or getWrapperData(obj)['name']
def _getSelWorkflow(self):
reqWorkflow = self.request.get('workflow', u'')
pi_container = getAdapter(self.context, IProcessInstanceContainer)
if reqWorkflow is u'':
available_instances = pi_container.keys()
if len(available_instances) > 0:
pi = pi_container[available_instances[0]]
else:
pi = None
else:
pi = pi_container[reqWorkflow]
return pi
def _getProcessDefinition(self, processInstance):
ws = getService(self.context, Workflows)
return ws.getProcessDefinition(processInstance.processDefinitionName)
=== Added File Zope3/src/zope/app/browser/workflow/stateful/instance_manage.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css"></style>
</head>
<body>
<div metal:fill-slot="body">
<div metal:define-macro="contents">
<div metal:define-macro="contents_selectWorkflow"
tal:define="workflow request/workflow | nothing">
<div tal:condition="not:workflow" tal:omit-tag="">
<form name="containerContentsForm" method="get" action="@@workflows.html"
tal:define="container_contents view/listContentInfo"
tal:condition="container_contents">
Workflow:
<select name="workflow" size="1">
<option tal:repeat="workflow container_contents"
tal:attributes="value workflow/id"
tal:content="workflow/name"></option>
</select>
<input type="submit" value="choose" />
</form>
</div>
<div tal:condition="workflow" tal:omit-tag="">
Workflow: <div tal:replace="view/getWorkflowTitle"></div>
</div>
</div>
<div metal:define-macro="contents_changeState">
</div>
</div>
<br/>
<div metal:define-macro="contents_transitions"
tal:define="info view/getTransitions"
tal:condition="info">
Current Status: <div tal:replace="info/status"/>
<br/>
Possible State Changes:
<form action="@@fireTransition.html" method="get">
<input type="hidden" name="workflow" tal:attributes="value request/workflow | nothing">
<div tal:repeat="trans info/transitions"
tal:condition="info/transitions | nothing"
tal:omit-tag="">
<input type="radio"
name="selTransition"
tal:attributes="value trans/name"/> <span tal:replace="trans/title"/><br/>
</div>
<input type="submit" value="do it">
</form>
</div>
</div>
</body>
</html>
=== Added File Zope3/src/zope/app/browser/workflow/stateful/interfaces.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Interfaces for stateful workflow.
$Id: interfaces.py,v 1.1 2003/05/08 17:27:18 jack-e Exp $
"""
from zope.interface import Interface
class IContentFilterAdapter(Interface):
def filterListByState(objList, state, workflow='default'):
"""Filter a list of objects according to given workflow and state
objList ... list of objects
state ... name of a state (of the given workflow) in which the result
objects must be
workflow ... name of a workflow to which result objects must be attached
"""
def filterObjectByState(object, state, workflow='default'):
"""Filter an object according to the given workflow and state."""
=== Added File Zope3/src/zope/app/browser/workflow/stateful/published_content.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css"></style>
</head>
<body>
<div metal:fill-slot="body">
<div tal:repeat="obj view/listPublishedItems"
tal:omit-tag="">
<div tal:content="obj/url"/><br/>
</div>
</div>
</body>
</html>