replace moderate comments table with a subclass of the standard Plone folder-listing table. this basically breaks all functionality (filter, bulk actions) and kss actions are not working yet, but the pagination is working.

svn path=/plone.app.discussion/trunk/; revision=27698
This commit is contained in:
Timo Stollenwerk 2009-06-28 11:49:00 +00:00
parent 4cc26a6421
commit abb0334c1d
5 changed files with 596 additions and 14 deletions

View File

@ -0,0 +1,104 @@
<!-- Navigation -->
<div class="listingBar"
i18n:domain="plone"
metal:define-macro="navigation"
tal:define="batch view/batch"
tal:condition="batch/multiple_pages">
<span class="previous"
tal:condition="batch/has_previous">
<a href=""
tal:attributes="href string:${view/url}?pagenumber=${batch/previouspage}&amp;sort_on=${request/sort_on|string:getObjPositionInParent}">
&laquo;
<span i18n:translate="batch_previous_x_items" tal:omit-tag="">
Previous
<span i18n:name="number" tal:omit-tag="" tal:content="batch/pagesize">n</span>
items
</span>
</a>
</span>
<span class="next"
tal:condition="batch/has_next">
<a href=""
tal:attributes="href string:${view/url}?pagenumber=${batch/nextpage}&amp;sort_on=${request/sort_on|string:getObjPositionInParent}">
<span i18n:translate="batch_next_x_items" tal:omit-tag="">
Next
<span i18n:name="number" tal:omit-tag="" tal:content="batch/next_item_count">n</span>
items
</span>
&raquo;
</a>
</span>
<!-- Link to first -->
<span tal:condition="batch/show_link_to_first">
<a href=""
tal:attributes="href string:${view/url}?pagenumber=1&amp;sort_on=${request/sort_on|string:getObjPositionInParent}">1</a>
<span tal:condition="batch/second_page_not_in_navlist"
tal:omit-tag="">
...
</span>
</span>
<!-- Pagelist with quantum leap links to previous pages for quick navigation -->
<!--
<span tal:repeat="linklist python:batch.navurls(request.form, batch.leapback)"
tal:condition="batch/leapback"
tal:omit-tag="" >
<a href=""
tal:define="page python:linklist[0];
query python:linklist[1];"
tal:content="page"
tal:attributes="href python: '%s?%s' % (url,query)" >
</a>
...
</span>
-->
<!-- Pagelist with links to previous pages for quick navigation -->
<span tal:repeat="pagenumber batch/previous_pages"
tal:omit-tag="" >
<a href="" tal:content="pagenumber"
tal:attributes="href string:${view/url}?pagenumber=$pagenumber&amp;sort_on=${request/sort_on|string:getObjPositionInParent}"/>
</span>
<!-- Current page -->
<span tal:condition="batch/navlist"
tal:omit-tag="">
[<span tal:content="batch/pagenumber">Current page number</span>]
</span>
<!-- Pagelist with links to next pages for quick navigation -->
<span tal:repeat="pagenumber batch/next_pages"
tal:omit-tag="" >
<a href="" tal:content="pagenumber"
tal:attributes="href string:${view/url}?pagenumber=$pagenumber&amp;sort_on=${request/sort_on|string:getObjPositionInParent}"/>
</span>
<!-- Pagelist with quantum leap links to next pages for quick navigation -->
<!--
<span tal:repeat="linklist python:batch.navurls(request.form, batch.leapforward)"
tal:condition="batch/leapforward"
tal:omit-tag="" >
...
<a href=""
tal:define="page python:linklist[0];
query python:linklist[1];"
tal:content="page"
tal:attributes="href python: '%s?%s' % (url,query)" >
</a>
</span>
-->
<!-- Link to last -->
<span tal:condition="batch/show_link_to_last">
<span tal:condition="batch/before_last_page_not_in_navlist"
tal:omit-tag="">
...
</span>
<a href=""
tal:attributes="href string:${view/url}?pagenumber=${batch/lastpage}&amp;sort_on=${request/sort_on|string:getObjPositionInParent}"
tal:content="batch/lastpage">3457</a>
</span>
</div>

View File

@ -8,6 +8,24 @@
<!-- Traversal adapter -->
<adapter factory=".traversal.ConversationNamespace" name="conversation" />
<!--
<browser:page
for="*"
class=".moderation.ReviewCommentsView"
name="view"
template="foldercontents.pt"
permission="cmf.ListFolderContents" />
-->
<browser:page
for="*"
class=".moderation.ReviewCommentsKSSView"
attribute="update_table"
name="reviewcomments_update_table"
permission="cmf.ManagePortal" />
<!-- Moderation view -->
<browser:page
for="Products.CMFCore.interfaces.ISiteRoot"

View File

@ -70,9 +70,19 @@
-->
</ul>
<form name="folderContentsForm"
method="post"
action="folder_object"
tal:attributes="action context/absolute_url"
class="kssattr-serveraction-foldercontents_update_table">
<!-- TODO: change class and replace KSS methods -->
<div tal:replace="structure view/contents_table"></div>
<input tal:replace="structure context/@@authenticator/authenticator" />
</form>
<form method="post"
action="#"
class="kssattr-serveraction-foldercontents_update_table"
class="kssattr-serveraction-moderatecomments_update_table"
tal:attributes="action string:${context/absolute_url}/@@bulk-actions">
<select name="form.select.BulkAction">
<option selected="selected" value="-1" i18n:translate="title_bulkactions">Bulk Actions</option>
@ -88,19 +98,32 @@
name="form.button.BulkAction"
i18n:attributes="value label_apply;" />
<!--
<table id="review-comments" class="listing" style="width: 100%" tal:condition="items">
<thead>
<tr>
<th colspan="7" class="nosort"
i18n:translate="label_select_all">
Select:
<a tal:attributes="href string:#"
id="foldercontents-selectall"
i18n:name="label_link_all"
i18n:translate="label_all">
All
</a>
<tr tal:condition="not:view/table/selectcurrentbatch">
<th colspan="7" class="nosort"><span i18n:translate="label_select" tal:omit-tag="">Select:</span> <a i18n:translate="label_all" tal:attributes="href view/table/selectscreen_url" id="foldercontents-selectall" class="update-selection">All</a></th>
</tr>
<tr tal:condition="view/table/show_select_all_items">
<th colspan="7" class="nosort">
<span tal:omit-tag="" i18n:translate="tableheading_all_items_selected">
All <tal:block replace="view/table/batch/items_on_page" i18n:name="count"/> items on this
page are selected.
</span>
<a tal:attributes="href view/table/selectall_url"
id="foldercontents-selectall-completebatch" class="update-selection"
i18n:translate="tableheading_select_all_items">Select all
<tal:block replace="view/table/batch/size" i18n:name="count"/> items in this folder.</a>
</th>
</tr>
<tr tal:condition="view/table/selectall">
<th colspan="7" class="nosort">
<span tal:omit-tag="" i18n:translate="tableheading_all_items_selected">
All <tal:block replace="view/table/batch/size" i18n:name="count"/> items in this folder
are selected.
</span>
<a tal:attributes="href view/table/selectnone_url" i18n:translate="tableheading_clear_selection"
id="foldercontents-clearselection" class="update-selection">Clear selection</a>
</th>
</tr>
<tr>
@ -110,7 +133,7 @@
<th i18n:translate="heading_context">In Response To</th>
<th i18n:translate="heading_subject">Subject</th>
<th i18n:translate="heading_comment">Comment</th>
<th i18n:translate="heading_action">Action</th>
<th i18n:translate="heading_action" class="nosort">Action</th>
</tr>
</thead>
<tbody>
@ -174,7 +197,25 @@
</tr>
</tal:block>
</tbody>
<tfooter tal:condition="not:view/table/within_batch_size">
<tr tal:condition="not:view/table/show_all">
<th colspan="7" class="nosort">
<a tal:attributes="href view/table/show_all_url"
i18n:translate="label_show_all"
id="foldercontents-show-all" class="update-selection">Show all items</a>
</th>
</tr>
<tr tal:condition="view/table/show_all">
<th colspan="7" class="nosort">
<a tal:attributes="href view/table/view_url"
i18n:translate="label_show_batched"
id="foldercontents-show-batched" class="update-selection">Show batched</a>
</th>
</tr>
</tfooter>
</table>
-->
</form>
</tal:main-macro>
</metal:main>

View File

@ -1,16 +1,44 @@
from plone.app.content.browser.tableview import Table, TableKSSView
from Acquisition import aq_inner, aq_parent
from Products.Five.browser import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from zope.app.pagetemplate import ViewPageTemplateFile as VPTF
from Products.CMFCore.utils import getToolByName
from zope.component import getMultiAdapter
from zope.interface import implements
from zope.i18n import translate
from AccessControl import Unauthorized
from Acquisition import aq_parent, aq_inner
from OFS.interfaces import IOrderedContainer
from Products.ATContentTypes.interface import IATTopic
from Products.CMFCore.utils import getToolByName
from Products.CMFPlone.utils import safe_unicode
from Products.Five import BrowserView
from plone.memoize import instance
from plone.app.content.browser.interfaces import IFolderContentsView
from plone.app.content.browser.tableview import Table, TableKSSView
from Products.CMFPlone.interfaces import IPloneSiteRoot
import urllib
class View(BrowserView):
"""
"""Moderation View
"""
template = ViewPageTemplateFile('moderation.pt')
def contents_table(self):
table = ReviewCommentsTable(aq_inner(self.context), self.request)
return table.render()
def __call__(self):
context = aq_inner(self.context)
@ -78,6 +106,172 @@ class View(BrowserView):
def comments_spam(self, start=0, size=None):
return None
class ReviewTable(Table):
render = VPTF("table.pt")
batching = VPTF("batching.pt")
class ReviewCommentsTable(object):
"""The reviewcomments table renders the table and its actions.
"""
def __init__(self, context, request, contentFilter={}):
self.context = context
self.request = request
self.contentFilter = contentFilter
url = context.absolute_url()
view_url = url + '/@@moderate-comments'
self.table = ReviewTable(request, url, view_url, self.items)
def render(self):
return self.table.render()
@property
def items(self):
"""
"""
context = aq_inner(self.context)
self.state = self.request.get('review_state', 'pending')
self.transition = self.request.get('publish_transition', 'pending')
self.limit = self.request.get('limit', 100)
catalog = getToolByName(context, 'portal_catalog')
brains = catalog(
portal_type='Discussion Item',
sort_on='created',
sort_limit=self.limit,
)
plone_utils = getToolByName(context, 'plone_utils')
plone_view = getMultiAdapter((context, self.request), name=u'plone')
portal_workflow = getToolByName(context, 'portal_workflow')
portal_properties = getToolByName(context, 'portal_properties')
portal_types = getToolByName(context, 'portal_types')
site_properties = portal_properties.site_properties
use_view_action = site_properties.getProperty('typesUseViewActionInListings', ())
browser_default = context.browserDefault()
results = []
for i, obj in enumerate(brains):
if (i + 1) % 2 == 0:
table_row_class = "draggable even"
else:
table_row_class = "draggable odd"
url = obj.getURL()
path = obj.getPath or "/".join(obj.getPhysicalPath())
icon = plone_view.getIcon(obj);
type_class = 'contenttype-' + plone_utils.normalizeString(
obj.portal_type)
review_state = obj.review_state
state_class = 'state-' + plone_utils.normalizeString(review_state)
relative_url = obj.getURL(relative=True)
type_title_msgid = portal_types[obj.portal_type].Title()
url_href_title = u'%s: %s' % (translate(type_title_msgid,
context=self.request),
safe_unicode(obj.Description))
modified = plone_view.toLocalizedTime(
obj.ModificationDate, long_format=1)
obj_type = obj.Type
#if obj_type in use_view_action:
# view_url = url + '/view'
#elif obj.is_folderish:
# view_url = url + "/moderate-comments"
#else:
# view_url = url
view_url = url + "/@@moderate-comments"
is_browser_default = len(browser_default[1]) == 1 and (
obj.id == browser_default[1][0])
results.append(dict(
url = url,
url_href_title = url_href_title,
id = obj.getId,
quoted_id = urllib.quote_plus(obj.getId),
path = path,
title_or_id = obj.pretty_title_or_id(),
obj_type = obj_type,
size = obj.getObjSize,
modified = modified,
icon = icon.html_tag(),
type_class = type_class,
wf_state = review_state,
state_title = portal_workflow.getTitleForStateOnType(review_state,
obj_type),
state_class = state_class,
is_browser_default = is_browser_default,
folderish = obj.is_folderish,
relative_url = relative_url,
view_url = view_url,
table_row_class = table_row_class,
is_expired = context.isExpired(obj),
))
return results
@property
def orderable(self):
"""
"""
return IOrderedContainer.providedBy(aq_inner(self.context))
@property
def show_sort_column(self):
return self.orderable and self.editable
@property
def editable(self):
"""
"""
context_state = getMultiAdapter((aq_inner(self.context), self.request),
name=u'plone_context_state')
return context_state.is_editable()
@property
def buttons(self):
buttons = []
context = aq_inner(self.context)
portal_actions = getToolByName(context, 'portal_actions')
button_actions = portal_actions.listActionInfos(object=context, categories=('folder_buttons', ))
# Do not show buttons if there is no data, unless there is data to be
# pasted
if not len(self.items):
if self.context.cb_dataValid():
for button in button_actions:
if button['id'] == 'paste':
return [self.setbuttonclass(button)]
else:
return []
for button in button_actions:
# Make proper classes for our buttons
if button['id'] != 'paste' or context.cb_dataValid():
buttons.append(self.setbuttonclass(button))
return buttons
def setbuttonclass(self, button):
if button['id'] == 'paste':
button['cssclass'] = 'standalone'
else:
button['cssclass'] = 'context'
return button
class ReviewCommentsKSSView(TableKSSView):
table = ReviewCommentsTable
class DeleteComment(BrowserView):
"""Delete a comment from a conversation
"""

View File

@ -0,0 +1,225 @@
<div id="folderlisting-main-table"
i18n:domain="plone">
<input type="hidden" name="sort_on"
tal:attributes="value request/sort_on|string:getObjPositionInParent"
/>
<input type="hidden" name="pagenumber" tal:attributes="value view/batch/pagenumber"/>
<input type="hidden" name="show_all" tal:attributes="value view/show_all"/>
<input type="hidden" name="orig_template" tal:attributes="value view/viewname"/>
<tal:block condition="view/selectall">
<input type="hidden" name="paths:list"
tal:repeat="item view/batch/items_not_on_page"
tal:attributes="value item/path"/>
</tal:block>
<!-- <div metal:use-macro="context/document_actions/macros/document_actions">
Document actions (print, sendto etc)
</div> -->
<p class="discreet"
tal:condition="not: view/batch"
i18n:translate="description_no_visible_items_add_paste">
This folder has no visible items. To add content, press the
add button, or paste content from another location.
</p>
<metal:listing define-macro="folder_listing"
tal:define="nosortclass view/get_nosort_class">
<div class="visualClear" id="clear-space-before-navigation"><!-- --></div>
<div tal:replace="structure view/batching" tal:condition="not:view/show_all"/>
<table class="listing"
id="listing-table"
summary="Content listing"
i18n:attributes="summary summary_content_listing;"
tal:condition="view/items">
<thead>
<tr tal:condition="not:view/selectcurrentbatch">
<th colspan="6" class="nosort"><span i18n:translate="label_select" tal:omit-tag="">Select:</span> <a i18n:translate="label_all" tal:attributes="href view/selectscreen_url" id="foldercontents-selectall" class="update-selection">All</a></th>
</tr>
<tr tal:condition="view/show_select_all_items">
<th colspan="6" class="nosort">
<span tal:omit-tag="" i18n:translate="tableheading_all_items_selected">
All <tal:block replace="view/batch/items_on_page" i18n:name="count"/> items on this
page are selected.
</span>
<a tal:attributes="href view/selectall_url"
id="foldercontents-selectall-completebatch" class="update-selection"
i18n:translate="tableheading_select_all_items">Select all
<tal:block replace="view/batch/size" i18n:name="count"/> items in this folder.</a>
</th>
</tr>
<tr tal:condition="view/selectall">
<th colspan="6" class="nosort">
<span tal:omit-tag="" i18n:translate="tableheading_all_items_selected">
All <tal:block replace="view/batch/size" i18n:name="count"/> items in this folder
are selected.
</span>
<a tal:attributes="href view/selectnone_url" i18n:translate="tableheading_clear_selection"
id="foldercontents-clearselection" class="update-selection">Clear selection</a>
</th>
</tr>
<tr>
<th class="nosort">&nbsp;</th>
<th class="nosort column"
id="foldercontents-title-column">&nbsp;<tal:title i18n:translate="listingheader_title"
>Title</tal:title>&nbsp;</th>
<!--<th class="nosort column"
id="foldercontents-size-column">&nbsp;<tal:size i18n:translate="listingheader_size"
>Size</tal:size>&nbsp;</th>-->
<th class="nosort column"
id="foldercontents-modified-column">&nbsp;<tal:modified i18n:translate="listingheader_modified"
>Modified</tal:modified>&nbsp;</th>
<th class="nosort column"
id="foldercontents-status-column">&nbsp;<tal:state i18n:translate="listingheader_status"
>State</tal:state>&nbsp;</th>
<th class="nosort column"
id="foldercontents-order-column"
tal:condition="view/show_sort_column">
&nbsp;<tal:order i18n:translate="listingheader_order">Order</tal:order>&nbsp;</th>
<th class="nosort column"
id="foldercontents-action-column">&nbsp;<tal:title i18n:translate="listingheader_action"
>Action</tal:title>&nbsp;</th>
</tr>
</thead>
<metal:block tal:condition="view/batch">
<tbody>
<tal:items tal:repeat="item view/batch">
<tr tal:attributes="class item/table_row_class;
id string:folder-contents-item-${item/id};" >
<tal:comment replace="nothing">
* We have to check if the browserDefault stuff is really necessary
* Create title_or_id metadata in the catalog (why not just use item.Title or item.getId? (alecm))
</tal:comment>
<td class="notDraggable">
<input type="checkbox"
class="noborder"
name="paths:list" id="#"
value="#"
tal:attributes="value item/path;
id string:cb_${item/id};
checked item/checked;
alt string:Select ${item/title_or_id};
title string:Select ${item/title_or_id}" />
<input type="hidden" name="selected_obj_paths:list" value="#"
tal:attributes="value item/relative_url" />
<label tal:content="item/title_or_id"
tal:attributes="for string:cb_${item/id}"
class="hiddenStructure">
Item Title
</label>
</td>
<td>
<span tal:attributes="class item/type_class">
<img tal:replace="structure item/icon" />
<a href="#" tal:attributes="href item/view_url;
title item/url_href_title;
class item/state_class;">
<strong tal:omit-tag="not: item/is_browser_default"
tal:content="item/title_or_id"/>
</a>
</span>
<span class="state-expired"
tal:condition="item/is_expired"
i18n:translate="time_expired">expired</span>
</td>
<!--<td>
<span tal:condition="not: item/size"> &nbsp; </span>
<span tal:condition="item/size"
tal:content="item/size"
tal:attributes="class item/state_class"> size </span>
</td>-->
<td tal:content="item/modified"
tal:attributes="class item/state_class">
08/19/2001 03:01 AM
</td>
<td>
<span i18n:translate=""
tal:condition="item/state_title"
tal:content="item/state_title"
tal:attributes="class item/state_class" />
<span tal:condition="not: item/state_title">&nbsp;</span>
</td>
<td tal:condition="view/show_sort_column" class="draggable">
<a href=""
title="Move item up"
i18n:attributes="title title_move_item_up;"
tal:attributes="href string:${view/base_url}/folder_position?position=up&amp;id=${item/quoted_id}">
&#9650;
</a>
&nbsp;
<a href=""
title="Move item down"
i18n:attributes="title title_move_item_down;"
tal:attributes="href string:${view/base_url}/folder_position?position=down&amp;id=${item/quoted_id}">
&#9660;
</a>
</td>
<td style="width: 11em">
<form action=""
class="background-form"
method="post"
style="display: inline"
tal:attributes="action string:${item/url}/@@moderate-publish-comment"
tal:condition="python:True or item.wf_state == 'pending'">
<input type="hidden" name="comment_id" tal:attributes="value item/id" />
<input type="hidden" name="workflow_action" tal:attributes="value string:publish
todo string:view/transition" />
<input class="context comment-publish-button"
type="submit"
value="Publish"
i18n:attributes="value label_publish"
/>
</form>
<form action=""
method="post"
class="background-form"
style="display: inline"
tal:attributes="action string:${item/url}/@@moderate-delete-comment">
<input type="hidden" name="comment_id" tal:attributes="value item/id" />
<input class="destructive comment-delete-button"
type="submit"
value="Delete"
i18n:attributes="value label_delete;"
/>
</form>
</td>
</tr>
</tal:items>
</tbody>
<tfooter tal:condition="not:view/within_batch_size">
<tr tal:condition="not:view/show_all">
<th colspan="6" class="nosort">
<a tal:attributes="href view/show_all_url"
i18n:translate="label_show_all"
id="foldercontents-show-all" class="update-selection">Show all items</a>
</th>
</tr>
<tr tal:condition="view/show_all">
<th colspan="6" class="nosort">
<a tal:attributes="href view/view_url"
i18n:translate="label_show_batched"
id="foldercontents-show-batched" class="update-selection">Show batched</a>
</th>
</tr>
</tfooter>
</metal:block>
</table>
<div tal:replace="structure view/batching" tal:condition="not:view/show_all"/>
<tal:buttons tal:repeat="button view/buttons">
<input class="context"
type="submit"
name=""
value=""
i18n:attributes="value"
tal:attributes="value button/title; name button/url; class button/cssclass" />
</tal:buttons>
</metal:listing>
</div>