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:
parent
768b2095de
commit
90440cfeca
@ -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)
|
|
||||||
|
@ -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"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user