This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
pfwbged.collection/src/pfwbged/collection/portlet.py

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.")