add bulk actions and filter to the moderation view.

move delete- and publish-comment methods from comment.py to moderation.py.

svn path=/plone.app.discussion/trunk/; revision=27670
This commit is contained in:
Timo Stollenwerk 2009-06-26 14:57:45 +00:00
parent 768b2095de
commit 90440cfeca
5 changed files with 152 additions and 89 deletions

View File

@ -20,8 +20,6 @@ from Products.CMFCore.utils import getToolByName
from Products.CMFPlone import PloneMessageFactory as _ from Products.CMFPlone import PloneMessageFactory as _
from Products.statusmessages.interfaces import IStatusMessage
from plone.registry.interfaces import IRegistry from plone.registry.interfaces import IRegistry
from plone.app.layout.viewlets.common import ViewletBase from plone.app.layout.viewlets.common import ViewletBase
@ -284,41 +282,3 @@ class ReplyToComment(BrowserView):
# Todo: Temporarily remove the "#comment-" to fix a bug # Todo: Temporarily remove the "#comment-" to fix a bug
# in CMFPlone/skins/plone_ecmascript/form_tabbing.js # in CMFPlone/skins/plone_ecmascript/form_tabbing.js
self.request.response.redirect(aq_parent(aq_inner(context)).absolute_url() + '#' + str(reply_to_comment_id)) self.request.response.redirect(aq_parent(aq_inner(context)).absolute_url() + '#' + str(reply_to_comment_id))
class DeleteComment(BrowserView):
"""Delete a comment from a conversation
"""
def __call__(self):
context = aq_inner(self.context)
comment_id = self.context.id
conversation = aq_parent(context)
del conversation[comment_id]
# Todo: i18n
IStatusMessage(self.request).addStatusMessage(
_('Comment %s deleted' % comment_id),
type="info")
return context.REQUEST.RESPONSE.redirect(context.REQUEST.HTTP_REFERER)
class PublishComment(BrowserView):
"""Publish a comment
"""
def __call__(self):
comment = aq_inner(self.context)
comment_id = self.context.id
workflow_action = self.request.form['workflow_action']
portal_workflow = getToolByName(comment, 'portal_workflow')
portal_workflow.doActionFor(comment, workflow_action)
# Todo: i18n
IStatusMessage(self.request).addStatusMessage(
_('Workflow action for commment %s changed (%s)' % (comment_id, workflow_action)),
type="info")
return self.context.REQUEST.RESPONSE.redirect(self.context.REQUEST.HTTP_REFERER)

View File

@ -17,12 +17,21 @@
permission="cmf.ManagePortal" permission="cmf.ManagePortal"
/> />
<!-- Moderation bulk actions view -->
<browser:page
for="Products.CMFCore.interfaces.ISiteRoot"
name="bulk-actions"
layer="..interfaces.IDiscussionLayer"
class=".moderation.BulkActionsView"
permission="cmf.ManagePortal"
/>
<!-- Delete comment view --> <!-- Delete comment view -->
<browser:view <browser:view
for="plone.app.discussion.interfaces.IComment" for="plone.app.discussion.interfaces.IComment"
name="moderate-delete-comment" name="moderate-delete-comment"
layer="..interfaces.IDiscussionLayer" layer="..interfaces.IDiscussionLayer"
class=".comments.DeleteComment" class=".moderation.DeleteComment"
permission="plone.app.discussion.ReviewComments" permission="plone.app.discussion.ReviewComments"
/> />
@ -31,7 +40,7 @@
for="plone.app.discussion.interfaces.IComment" for="plone.app.discussion.interfaces.IComment"
name="moderate-publish-comment" name="moderate-publish-comment"
layer="..interfaces.IDiscussionLayer" layer="..interfaces.IDiscussionLayer"
class=".comments.PublishComment" class=".moderation.PublishComment"
permission="plone.app.discussion.ReviewComments" permission="plone.app.discussion.ReviewComments"
/> />

View File

@ -35,61 +35,56 @@
<metal:main fill-slot="main"> <metal:main fill-slot="main">
<tal:main-macro metal:define-macro="main" <tal:main-macro metal:define-macro="main"
tal:define="items view/comments_pending_review"> tal:define="items view/comments">
<h1 class="documentFirstHeading" i18n:translate="title_review"> <h1 class="documentFirstHeading" i18n:translate="title_review">
Review comments Review comments
</h1> </h1>
<p id="no-comments-message" i18n:translate="message_nothing_to_review"
tal:attributes="style python:len(items) > 0 and 'display: none' or None">
No comments to review. To look for more comments,
<a i18n:name="refresh-link" i18n:translate="message_click_to_refresh"
tal:attributes="href context/@@plone_context_state/current_page_url">
click here to refresh.
</a>
</p>
<p id="comments-help" tal:condition="items" class="discreet" i18n:translate="description_review">
Comments for review are listed below. For each one, click
<em>Delete</em> to remove the comment or <em>Publish</em> to
publish it. Note that at most <span i18n:name="limit" tal:content="view/limit" />
comments will be shown at a time. If there are further comments,
you will be able to see them once you have published or deleted
the first batch.
</p>
<ul class="filter"> <ul class="filter">
<li class="all"> <li class="all">
<a class="current" href="#" i18n:translate="title_filter_all">All</a> <form method="post"
| action="#"
tal:attributes="action string:${context/absolute_url}/@@moderate-comments">
<input type="submit" value="All" class="context" />
</form>
</li> </li>
<li class="moderated"> <li class="pending">
<a href="#" i18n:translate="title_filter_pending">Pending</a> <form method="post" action="#" tal:attributes="action string:${context/absolute_url}/@@moderate-comments">
| <input type="hidden" name="form.button.FilterPending" value="1" />
<input type="submit" value="Pending" class="context" />
</form>
</li> </li>
<li class="approved"> <li class="approved">
<a href="#" i18n:translate="title_filter_approved">Approved</a> <form method="post" action="#" tal:attributes="action string:${context/absolute_url}/@@moderate-comments">
| <input type="hidden" name="form.button.FilterPublished" value="1" />
<input type="submit" value="Published" class="context" />
</form>
</li> </li>
<!--
<li class="spam"> <li class="spam">
<a href="#" i18n:translate="title_filter_spam">Spam</a> <a href="#"
tal:attributes="href string:${context/absolute_url}/@@comments-spam"
i18n:translate="title_filter_spam">Spam</a>
</li> </li>
-->
</ul> </ul>
<select name="bulkaction"> <form method="post" action="#" tal:attributes="action context/absolute_url">
<option selected="selected" value="-1" i18n:translate="title_bulkactions">Bulk Actions</option> <select name="bulkaction">
<option value="unapprove" i18n:translate="bulkactions_unapprove">Unapprove</option> <option selected="selected" value="-1" i18n:translate="title_bulkactions">Bulk Actions</option>
<option value="approve" i18n:translate="bulkactions_approve">Approve</option> <option value="unapprove" i18n:translate="bulkactions_unapprove">Unapprove</option>
<option value="markasspam" i18n:translate="bulkactions_markasspam">Mark as Spam</option> <option value="approve" i18n:translate="bulkactions_approve">Approve</option>
<option value="delete" i18n:translate="bulkactions_delete">Delete</option> <option value="markasspam" i18n:translate="bulkactions_markasspam">Mark as Spam</option>
</select> <option value="delete" i18n:translate="bulkactions_delete">Delete</option>
<input id="dobulkaction" </select>
type="submit" <input id="dobulkaction"
class="standalone" type="submit"
value="Apply" class="standalone"
name="bulkdoaction" value="Apply"
i18n:attributes="value label_apply;" /> name="form.button.BulkAction"
i18n:attributes="value label_apply;" />
</form>
<table id="review-comments" class="listing nosort" style="width: 100%" tal:condition="items"> <table id="review-comments" class="listing nosort" style="width: 100%" tal:condition="items">
<thead> <thead>
@ -152,7 +147,7 @@
style="display: inline" style="display: inline"
tal:attributes="action string:${item/getURL}/@@moderate-publish-comment"> tal:attributes="action string:${item/getURL}/@@moderate-publish-comment">
<input type="hidden" name="comment_id" tal:attributes="value item/getId" /> <input type="hidden" name="comment_id" tal:attributes="value item/getId" />
<input type="hidden" name="action" tal:attributes="value view/transition" /> <input type="hidden" name="workflow_action" tal:attributes="value view/transition" />
<input class="context comment-publish-button" <input class="context comment-publish-button"
type="submit" type="submit"
value="Publish" value="Publish"

View File

@ -12,12 +12,24 @@ class View(BrowserView):
template = ViewPageTemplateFile('moderation.pt') template = ViewPageTemplateFile('moderation.pt')
def __call__(self): def __call__(self):
context = aq_inner(self.context)
if self.request.has_key('form.button.FilterPending'):
self.comments = self.comments_pending()
elif self.request.has_key('form.button.FilterPublished'):
self.comments = self.comments_published()
else:
self.comments = self.comments_all()
return self.template() return self.template()
def cook(self, text): def cook(self, text):
return text return text
def comments_pending_review(self): def comments_workflow_enabled(self):
return True
def comments_all(self, start=0, size=None):
self.state = self.request.get('review_state', 'pending') self.state = self.request.get('review_state', 'pending')
self.transition = self.request.get('publish_transition', 'pending') self.transition = self.request.get('publish_transition', 'pending')
@ -27,9 +39,88 @@ class View(BrowserView):
catalog = getToolByName(context, 'portal_catalog') catalog = getToolByName(context, 'portal_catalog')
return catalog( return catalog(
path='/'.join(context.getPhysicalPath()), portal_type='Discussion Item',
sort_on='created',
sort_limit=self.limit,
)
def comments_pending(self, start=0, size=None):
self.state = self.request.get('review_state', 'pending')
self.transition = self.request.get('publish_transition', 'publish')
self.limit = self.request.get('limit', 100)
context = aq_inner(self.context)
catalog = getToolByName(context, 'portal_catalog')
return catalog(
portal_type='Discussion Item', portal_type='Discussion Item',
review_state=self.state, review_state=self.state,
sort_on='created', sort_on='created',
sort_limit=self.limit, sort_limit=self.limit,
) )
def comments_published(self, start=0, size=None):
self.state = self.request.get('review_state', 'pending')
self.transition = self.request.get('publish_transition', 'pending')
self.limit = self.request.get('limit', 100)
context = aq_inner(self.context)
catalog = getToolByName(context, 'portal_catalog')
return catalog(
portal_type='Discussion Item',
review_state='published',
sort_on='created',
sort_limit=self.limit,
)
def comments_spam(self, start=0, size=None):
return None
class DeleteComment(BrowserView):
"""Delete a comment from a conversation
"""
def __call__(self):
context = aq_inner(self.context)
comment_id = self.context.id
conversation = aq_parent(context)
del conversation[comment_id]
return context.REQUEST.RESPONSE.redirect(context.REQUEST.HTTP_REFERER)
class PublishComment(BrowserView):
"""Publish a comment
"""
def __call__(self):
comment = aq_inner(self.context)
comment_id = self.context.id
workflow_action = self.request.form['workflow_action']
portal_workflow = getToolByName(comment, 'portal_workflow')
portal_workflow.doActionFor(comment, workflow_action)
catalog = getToolByName(comment, 'portal_catalog')
catalog.reindexObject(comment)
comment.reindexObjectSecurity()
return self.context.REQUEST.RESPONSE.redirect(self.context.REQUEST.HTTP_REFERER)
class BulkActionsView(BrowserView):
"""Bulk actions (unapprove, approve, delete, mark as spam).
"""
def __call__(self):
context = aq_inner(self.context)
if self.request.has_key('form.button.BulkAction'):
bulkaction = self.request.get('form.bulkaction')
return bulkaction

View File

@ -50,8 +50,8 @@
/* Moderation View /* Moderation View
---------------------------------------------------------------- */ ---------------------------------------------------------------- */
.filter { ul.filter {
margin-left: 0 !important; margin: 0.5em 0 0.5em 0em;
} }
.filter li { .filter li {
display: inline; display: inline;
@ -60,3 +60,11 @@
.filter li a:link { .filter li a:link {
border-bottom: 0px solid transparent; border-bottom: 0px solid transparent;
} }
.filter form {
display: inline;
}
#dobulkaction {
margin: 0.2em 0;
}