[1572] | 1 | import random |
---|
| 2 | |
---|
| 3 | from zope.interface import implements |
---|
| 4 | from zope.component import getMultiAdapter |
---|
| 5 | |
---|
| 6 | from plone.portlets.interfaces import IPortletDataProvider |
---|
| 7 | from plone.portlet.collection import collection as base |
---|
| 8 | |
---|
| 9 | from zope import schema |
---|
| 10 | from zope.formlib import form |
---|
| 11 | |
---|
| 12 | from plone.memoize.instance import memoize |
---|
| 13 | from plone.memoize import ram |
---|
| 14 | from plone.memoize.compress import xhtml_compress |
---|
| 15 | |
---|
| 16 | from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile |
---|
| 17 | from plone.app.vocabularies.catalog import SearchableTextSourceBinder |
---|
[2704] | 18 | from zope.schema import ValidationError |
---|
[1572] | 19 | from plone.app.form.widgets.uberselectionwidget import UberSelectionWidget |
---|
| 20 | |
---|
| 21 | from Products.ATContentTypes.interface import IATTopic |
---|
[2704] | 22 | from Products.CMFPlone.PloneBatch import Batch |
---|
[1572] | 23 | from plone.portlet.collection.collection import ICollectionPortlet |
---|
| 24 | |
---|
| 25 | from quintagroup.portlet.collection import MessageFactory as _ |
---|
| 26 | |
---|
[2704] | 27 | MIN_BATCH_SIZE , MAX_BATCHSIZE = 1, 30 |
---|
| 28 | |
---|
| 29 | class NotValidBatchSizeValue(ValidationError): |
---|
| 30 | """This is not valid batch size value. |
---|
| 31 | |
---|
| 32 | """ |
---|
| 33 | |
---|
| 34 | def validate_batch_size(value): |
---|
| 35 | if MIN_BATCH_SIZE <= value <= MAX_BATCHSIZE: |
---|
| 36 | return True |
---|
| 37 | raise NotValidBatchSizeValue(value) |
---|
| 38 | |
---|
[1572] | 39 | class IQCollectionPortlet(ICollectionPortlet): |
---|
| 40 | """A portlet which based on plone.portlet.collection and |
---|
| 41 | adds more functionalities. |
---|
| 42 | """ |
---|
| 43 | |
---|
| 44 | item_attributes = schema.List(title=_(u"Attributes to display"), |
---|
| 45 | description=_(u"description_attributes", default=u"Select attributes to show for collection item."), |
---|
| 46 | required=False, |
---|
| 47 | default=[u"Title", u"Description"], |
---|
| 48 | value_type=schema.Choice(vocabulary='quintagroup.portlet.collection.vocabularies.PortletAttributesVocabulary')) |
---|
| 49 | |
---|
| 50 | styling = schema.Choice(title=_(u"Portlet style"), |
---|
| 51 | description=_(u"description_styling", default=u"Choose a css style for the porlet."), |
---|
| 52 | required=False, |
---|
| 53 | default=u"", |
---|
| 54 | vocabulary='quintagroup.portlet.collection.vocabularies.PortletCSSVocabulary') |
---|
| 55 | |
---|
| 56 | |
---|
| 57 | show_item_more = schema.Bool(title=_(u"Show more... link for collection items."), |
---|
| 58 | description=_(u"If enabled, a more... link will appear in the bottom of the each collection item, " |
---|
| 59 | "linking to the corresponding item."), |
---|
| 60 | required=True, |
---|
| 61 | default=True) |
---|
| 62 | |
---|
| 63 | link_title = schema.Bool(title=_(u"Link title."), |
---|
| 64 | description=_(u"If enabled, title will be shown as link to corresponding object. "), |
---|
| 65 | required=True, |
---|
| 66 | default=True) |
---|
| 67 | |
---|
[2704] | 68 | allow_batching = schema.Bool(title=_(u"Allow batching."), |
---|
| 69 | description=_(u"If enabled, items will be splited into pages."), |
---|
| 70 | required=False, |
---|
| 71 | default=False) |
---|
| 72 | |
---|
| 73 | batch_size = schema.Int(title=_(u"Batch size"), |
---|
| 74 | description=_("Amount of items per page" |
---|
| 75 | "(if not set 3 items will be displayed as default)."), |
---|
| 76 | required=False, |
---|
| 77 | default=3, |
---|
| 78 | constraint=validate_batch_size) |
---|
| 79 | |
---|
[1572] | 80 | class Assignment(base.Assignment): |
---|
| 81 | """ |
---|
| 82 | Portlet assignment. |
---|
| 83 | This is what is actually managed through the portlets UI and associated |
---|
| 84 | with columns. |
---|
| 85 | """ |
---|
| 86 | |
---|
| 87 | implements(IQCollectionPortlet) |
---|
| 88 | |
---|
| 89 | item_attributes = [u"Title", u"Description"] |
---|
| 90 | styling = u"" |
---|
| 91 | show_item_more = False |
---|
| 92 | link_title = True |
---|
| 93 | |
---|
| 94 | def __init__(self, header=u"", target_collection=None, limit=None, |
---|
| 95 | random=False, show_more=True, show_dates=False, |
---|
[2704] | 96 | item_attributes=[], styling=u"", show_item_more=False, |
---|
| 97 | link_title=True, allow_batching=False, batch_size=3): |
---|
[1572] | 98 | |
---|
| 99 | super(Assignment, self).__init__(header=header, |
---|
| 100 | target_collection=target_collection, limit=limit, |
---|
| 101 | random=random, show_more=show_more, show_dates=show_dates) |
---|
| 102 | |
---|
| 103 | if len(item_attributes) > 0: |
---|
| 104 | self.item_attributes = item_attributes |
---|
| 105 | self.styling = styling |
---|
| 106 | self.show_item_more = show_item_more |
---|
| 107 | self.link_title = link_title |
---|
[2704] | 108 | self.allow_batching = allow_batching |
---|
| 109 | self.batch_size = batch_size |
---|
[1572] | 110 | |
---|
| 111 | @property |
---|
| 112 | def title(self): |
---|
| 113 | """This property is used to give the title of the portlet in the |
---|
| 114 | "manage portlets" screen. Here, we use the title that the user gave. |
---|
| 115 | """ |
---|
| 116 | return self.header |
---|
[2704] | 117 | |
---|
[1572] | 118 | class Renderer(base.Renderer): |
---|
| 119 | """Portlet renderer. |
---|
| 120 | |
---|
| 121 | This is registered in configure.zcml. The referenced page template is |
---|
| 122 | rendered, and the implicit variable 'view' will refer to an instance |
---|
| 123 | of this class. Other methods can be added and referenced in the template. |
---|
| 124 | """ |
---|
| 125 | |
---|
| 126 | render = ViewPageTemplateFile('collection.pt') |
---|
[2704] | 127 | navigation = ViewPageTemplateFile('browser/templates/navigation.pt') |
---|
| 128 | items_listing = ViewPageTemplateFile('browser/templates/items_listing.pt') |
---|
[1572] | 129 | |
---|
| 130 | def showProperty(self, name): |
---|
| 131 | return name in self.data.item_attributes |
---|
| 132 | |
---|
[2704] | 133 | def batches(self): |
---|
| 134 | items = super(Renderer, self).results() |
---|
| 135 | delta = self.data.batch_size |
---|
| 136 | return [items[idx:idx + delta] for idx in range(0, len(items), delta)] |
---|
| 137 | |
---|
| 138 | def batch_navigation(self): |
---|
| 139 | return self.navigation(batches=self.batches()) |
---|
| 140 | |
---|
| 141 | def render_items(self): |
---|
| 142 | if self.data.allow_batching: |
---|
| 143 | return ''.join([self.items_listing(portlet_items=batch, |
---|
| 144 | page_number=str(index)) |
---|
| 145 | for index, batch in enumerate(self.batches())]) |
---|
| 146 | return self.items_listing(portlet_items=self.results()) |
---|
[1572] | 147 | |
---|
| 148 | class AddForm(base.AddForm): |
---|
| 149 | """Portlet add form. |
---|
| 150 | |
---|
| 151 | This is registered in configure.zcml. The form_fields variable tells |
---|
| 152 | zope.formlib which fields to display. The create() method actually |
---|
| 153 | constructs the assignment that is being added. |
---|
| 154 | """ |
---|
| 155 | form_fields = form.Fields(IQCollectionPortlet) |
---|
| 156 | form_fields['target_collection'].custom_widget = UberSelectionWidget |
---|
| 157 | |
---|
| 158 | label = _(u"Add Collection Portlet") |
---|
| 159 | description = _(u"This portlet display a listing of items from a Collection.") |
---|
| 160 | |
---|
| 161 | def create(self, data): |
---|
| 162 | return Assignment(**data) |
---|
| 163 | |
---|
| 164 | class EditForm(base.EditForm): |
---|
| 165 | """Portlet edit form. |
---|
| 166 | |
---|
| 167 | This is registered with configure.zcml. The form_fields variable tells |
---|
| 168 | zope.formlib which fields to display. |
---|
| 169 | """ |
---|
| 170 | |
---|
| 171 | form_fields = form.Fields(IQCollectionPortlet) |
---|
| 172 | form_fields['target_collection'].custom_widget = UberSelectionWidget |
---|
| 173 | |
---|
| 174 | label = _(u"Edit Collection Portlet") |
---|
| 175 | description = _(u"This portlet display a listing of items from a Collection.") |
---|