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