183 lines
5.4 KiB
Python
183 lines
5.4 KiB
Python
import random
|
|
|
|
from AccessControl import getSecurityManager
|
|
|
|
from zope.interface import implements
|
|
from zope.component import getMultiAdapter, getUtility
|
|
|
|
from plone.portlets.interfaces import IPortletDataProvider
|
|
from plone.app.portlets.portlets import base
|
|
|
|
from zope import schema
|
|
from zope.formlib import form
|
|
|
|
from plone.memoize.instance import memoize
|
|
|
|
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
|
|
from plone.app.vocabularies.catalog import SearchableTextSourceBinder
|
|
from plone.app.form.widgets.uberselectionwidget import UberSelectionWidget
|
|
|
|
from plone.i18n.normalizer.interfaces import IIDNormalizer
|
|
|
|
from searchview import QueryBuilder, get_appropriate_table_class
|
|
|
|
from pfwbged.collection import _
|
|
|
|
DEFAULT_LIMIT = 10
|
|
|
|
class ICollectionPortlet(IPortletDataProvider):
|
|
"""A portlet which renders the results of a collection object.
|
|
"""
|
|
|
|
header = schema.TextLine(
|
|
title=_(u"Portlet header"),
|
|
description=_(u"Title of the rendered portlet"),
|
|
required=True)
|
|
|
|
target_collection = schema.Choice(
|
|
title=_(u"Target collection"),
|
|
description=_(u"Find the collection which provides the items to list"),
|
|
required=True,
|
|
source=SearchableTextSourceBinder(
|
|
{'portal_type': ('Topic', 'Collection', 'pfwbgedcollection')},
|
|
default_query='path:'))
|
|
|
|
limit = schema.Int(
|
|
title=_(u"Limit"),
|
|
description=_(u"Specify the maximum number of items to show in the "
|
|
u"portlet. Leave this blank to show the default numer of items."),
|
|
default=DEFAULT_LIMIT,
|
|
required=False)
|
|
|
|
|
|
class Assignment(base.Assignment):
|
|
"""
|
|
Portlet assignment.
|
|
This is what is actually managed through the portlets UI and associated
|
|
with columns.
|
|
"""
|
|
|
|
implements(ICollectionPortlet)
|
|
|
|
header = u""
|
|
target_collection = None
|
|
limit = DEFAULT_LIMIT
|
|
random = False
|
|
show_more = True
|
|
show_dates = False
|
|
|
|
def __init__(self, header=u"", target_collection=None, limit=DEFAULT_LIMIT,
|
|
random=False, show_more=True, show_dates=False):
|
|
self.header = header
|
|
self.target_collection = target_collection
|
|
self.limit = limit
|
|
self.random = random
|
|
self.show_more = show_more
|
|
self.show_dates = show_dates
|
|
|
|
@property
|
|
def title(self):
|
|
"""This property is used to give the title of the portlet in the
|
|
"manage portlets" screen. Here, we use the title that the user gave.
|
|
"""
|
|
return self.header
|
|
|
|
|
|
class Renderer(base.Renderer):
|
|
|
|
_template = ViewPageTemplateFile('portlet.pt')
|
|
render = _template
|
|
|
|
def __init__(self, *args):
|
|
base.Renderer.__init__(self, *args)
|
|
|
|
@property
|
|
def available(self):
|
|
return True
|
|
|
|
def collection_url(self):
|
|
collection = self.collection()
|
|
if collection is None:
|
|
return None
|
|
else:
|
|
return collection.absolute_url()
|
|
|
|
def css_class(self):
|
|
header = self.data.header
|
|
normalizer = getUtility(IIDNormalizer)
|
|
return "portlet-collection-%s" % normalizer.normalize(header)
|
|
|
|
@memoize
|
|
def results(self):
|
|
return self._standard_results()
|
|
|
|
def _standard_results(self):
|
|
if self.collection() is None:
|
|
return []
|
|
|
|
query_builder = QueryBuilder(self.context, self.request)
|
|
sort_order = 'ascending'
|
|
if self.collection().sort_reversed:
|
|
sort_order = 'descending'
|
|
results = query_builder(self.collection().query,
|
|
sort_on=self.collection().sort_on,
|
|
sort_order=sort_order,
|
|
limit=self.data.limit or DEFAULT_LIMIT)
|
|
return results
|
|
|
|
@memoize
|
|
def collection(self):
|
|
collection_path = self.data.target_collection
|
|
if not collection_path:
|
|
return None
|
|
|
|
if collection_path.startswith('/'):
|
|
collection_path = collection_path[1:]
|
|
|
|
if not collection_path:
|
|
return None
|
|
|
|
portal_state = getMultiAdapter((self.context, self.request),
|
|
name=u'plone_portal_state')
|
|
portal = portal_state.portal()
|
|
if isinstance(collection_path, unicode):
|
|
# restrictedTraverse accepts only strings
|
|
collection_path = str(collection_path)
|
|
|
|
result = portal.unrestrictedTraverse(collection_path, default=None)
|
|
if result is not None:
|
|
sm = getSecurityManager()
|
|
if not sm.checkPermission('View', result):
|
|
result = None
|
|
return result
|
|
|
|
def table(self):
|
|
table_class = get_appropriate_table_class(self.context, self.collection().query)
|
|
table = table_class(self, self.request)
|
|
table.values = self.results()
|
|
table.update()
|
|
return table
|
|
|
|
|
|
class AddForm(base.AddForm):
|
|
|
|
form_fields = form.Fields(ICollectionPortlet)
|
|
form_fields['target_collection'].custom_widget = UberSelectionWidget
|
|
|
|
label = _(u"Add Collection Portlet")
|
|
description = _(u"This portlet displays a listing of items from a "
|
|
u"Collection.")
|
|
|
|
def create(self, data):
|
|
return Assignment(**data)
|
|
|
|
|
|
class EditForm(base.EditForm):
|
|
|
|
form_fields = form.Fields(ICollectionPortlet)
|
|
form_fields['target_collection'].custom_widget = UberSelectionWidget
|
|
|
|
label = _(u"Edit Collection Portlet")
|
|
description = _(u"This portlet displays a listing of items from a "
|
|
u"Collection.")
|