|
1 # |
|
2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net> |
|
3 # All Rights Reserved. |
|
4 # |
|
5 # This software is subject to the provisions of the Zope Public License, |
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
10 # FOR A PARTICULAR PURPOSE. |
|
11 # |
|
12 |
|
13 __docformat__ = 'restructuredtext' |
|
14 |
|
15 |
|
16 # import standard library |
|
17 |
|
18 # import interfaces |
|
19 from pyams_workflow.interfaces import IWorkflowManagedContent |
|
20 from zope.annotation.interfaces import IAttributeAnnotatable |
|
21 from zope.container.interfaces import IContainer |
|
22 from zope.contentprovider.interfaces import IContentProvider |
|
23 |
|
24 # import packages |
|
25 from pyams_security.schema import PermissionField |
|
26 from pyams_utils.schema import PersistentDict, PersistentList |
|
27 from zope.container.constraints import contains |
|
28 from zope.interface import invariant, Interface, Attribute, Invalid |
|
29 from zope.schema import List, TextLine, Object, Int, Bool, Choice |
|
30 |
|
31 from pyams_portal import _ |
|
32 |
|
33 |
|
34 class IPortlet(Interface): |
|
35 """Portlet interface""" |
|
36 |
|
37 name = Attribute("Portlet internal name") |
|
38 |
|
39 label = Attribute("Portlet visible name") |
|
40 |
|
41 permission = PermissionField(title="Portlet permission", |
|
42 description="Permission required to display permission", |
|
43 required=False) |
|
44 |
|
45 toolbar_image = Attribute("Porlet toolbar image") |
|
46 |
|
47 toolbar_css_class = Attribute("Portlet toolbar CSS class") |
|
48 |
|
49 |
|
50 class IPortletAddingInfo(Interface): |
|
51 """Portlet adding info interface""" |
|
52 |
|
53 portlet_name = Choice(title=_("Portlet"), |
|
54 vocabulary="PyAMS portal portlets") |
|
55 |
|
56 slot_name = Choice(title=_("Slot name"), |
|
57 description=_("Slot name to which this configuration applies"), |
|
58 required=True, |
|
59 vocabulary='PyAMS template slots') |
|
60 |
|
61 |
|
62 class IPortletConfiguration(Interface): |
|
63 """Portlet configuration interface""" |
|
64 |
|
65 template = Attribute("Template to which this configuration applis") |
|
66 |
|
67 slot_name = TextLine(title=_("Slot name"), |
|
68 description=_("Slot name to which this configuration applies"), |
|
69 required=True) |
|
70 |
|
71 portlet_name = Attribute("Portlet name") |
|
72 |
|
73 position = Int(title=_("Position"), |
|
74 description=_("Portlet position inside slot"), |
|
75 required=True, |
|
76 min=0) |
|
77 |
|
78 visible = Bool(title=_("Visible portlet?"), |
|
79 description=_("Select 'no' to hide this portlet. This will not break configuration inheritance..."), |
|
80 required=True, |
|
81 default=True) |
|
82 |
|
83 can_inherit = Attribute("Can inherit parent configuration?") |
|
84 |
|
85 inherit_parent = Bool(title=_("Inherit parent configuration?"), |
|
86 description=_("This option is only available if context's parent is using the same template " |
|
87 "and if this portlet is also present in the same slot..."), |
|
88 required=True, |
|
89 default=True) |
|
90 |
|
91 |
|
92 class IPortletContentProvider(IContentProvider): |
|
93 """Portlet content provider""" |
|
94 |
|
95 portlet = Object(title="Portlet utility", |
|
96 schema=IPortlet) |
|
97 |
|
98 configuration = Object(title="Portlet renderer configuration", |
|
99 schema=IPortletConfiguration) |
|
100 |
|
101 |
|
102 class IPortletPreviewer(IPortletContentProvider): |
|
103 """Portlet previewer interface |
|
104 |
|
105 A portlet previewer should be defined as an adapter for a context, |
|
106 a request, a view and a portlet |
|
107 """ |
|
108 |
|
109 |
|
110 class IPortletRenderer(IPortletContentProvider): |
|
111 """Portlet renderer interface |
|
112 |
|
113 A portlet renderer should be defined as an adapter for a context, |
|
114 a request, a view and a portlet |
|
115 """ |
|
116 |
|
117 |
|
118 class ISlot(Interface): |
|
119 """Portal template slot interface""" |
|
120 |
|
121 name = TextLine(title=_("Slot name"), |
|
122 description=_("This name must be unique in a given template"), |
|
123 required=True) |
|
124 |
|
125 row_id = Int(title=_("Row ID"), |
|
126 required=False) |
|
127 |
|
128 |
|
129 class ISlotConfiguration(Interface): |
|
130 """Portal slot configuration""" |
|
131 |
|
132 template = Attribute("Slot template") |
|
133 |
|
134 slot_name = TextLine(title="Slot name") |
|
135 |
|
136 visible = Bool(title=_("Visible slot?"), |
|
137 description=_("Select 'no' to hide this slot. This will not break configuration inheritance..."), |
|
138 required=True, |
|
139 default=True) |
|
140 |
|
141 can_inherit = Attribute("Can inherit parent configuration?") |
|
142 |
|
143 inherit_parent = Bool(title=_("Inherit parent configuration?"), |
|
144 description=_("This option is only available if context's parent template is using a " |
|
145 "template containing the same slot..."), |
|
146 required=True, |
|
147 default=True) |
|
148 |
|
149 xs_width = Int(title=_("Extra small device width"), |
|
150 description=_("Slot width, in columns count, on extra small devices (phones...); " |
|
151 "set to 0 to hide the portlet"), |
|
152 required=False, |
|
153 min=0, |
|
154 max=12) |
|
155 |
|
156 sm_width = Int(title=_("Small device width"), |
|
157 description=_("Slot width, in columns count, on small devices (tablets...); " |
|
158 "set to 0 to hide the portlet"), |
|
159 required=False, |
|
160 min=0, |
|
161 max=12) |
|
162 |
|
163 md_width = Int(title=_("Medium devices width"), |
|
164 description=_("Slot width, in columns count, on medium desktop devices (>= 992 pixels); " |
|
165 "set to 0 to hide the portlet"), |
|
166 required=False, |
|
167 min=0, |
|
168 max=12) |
|
169 |
|
170 lg_width = Int(title=_("Large devices width"), |
|
171 description=_("Slot width, in columns count, on large desktop devices (>= 1200 pixels); " |
|
172 "set to 0 to hide the portlet"), |
|
173 required=False, |
|
174 min=0, |
|
175 max=12) |
|
176 |
|
177 css_class = TextLine(title=_("CSS class"), |
|
178 description=_("CSS class applied to this slot"), |
|
179 required=False) |
|
180 |
|
181 def get_css_class(self, device=None): |
|
182 """Get current CSS class""" |
|
183 |
|
184 def get_width(self, device=None): |
|
185 """Get slot width for each or given device""" |
|
186 |
|
187 def set_width(self, width, device=None): |
|
188 """Set width in columns count for given device""" |
|
189 |
|
190 |
|
191 class ISlotRenderer(IContentProvider): |
|
192 """Slot renderer""" |
|
193 |
|
194 |
|
195 class IPortalTemplateConfiguration(Interface): |
|
196 """Portal template configuration interface""" |
|
197 |
|
198 rows = Int(title="Rows count", |
|
199 required=True, |
|
200 default=1, |
|
201 min=0) |
|
202 |
|
203 def add_row(self): |
|
204 """Add new row""" |
|
205 |
|
206 def set_row_order(self, order): |
|
207 """Change template rows order""" |
|
208 |
|
209 def delete_row(self, row_id): |
|
210 """Delete template row""" |
|
211 |
|
212 slot_names = PersistentList(title="Slot names", |
|
213 value_type=TextLine()) |
|
214 |
|
215 slot_order = PersistentDict(title="Solts order", |
|
216 key_type=Int(), # row index |
|
217 value_type=PersistentList(value_type=TextLine())) # slot name |
|
218 |
|
219 slots = PersistentDict(title="Slots portlets", |
|
220 description="List of slots associated with a given template", |
|
221 key_type=Int(), # row index |
|
222 value_type=PersistentDict(key_type=TextLine(), # slot name |
|
223 value_type=PersistentList(value_type=Choice( |
|
224 vocabulary='PyAMS portal portlets')), # portlet names |
|
225 required=False)) |
|
226 |
|
227 slot_config = PersistentDict(title="Slots configuration", |
|
228 key_type=TextLine(), # slot name |
|
229 value_type=Object(schema=ISlotConfiguration), |
|
230 required=False) |
|
231 |
|
232 def add_slot(self, slot_name, row_id=None): |
|
233 """Add slot with given name""" |
|
234 |
|
235 def set_slot_order(self, order): |
|
236 """Change template slots order""" |
|
237 |
|
238 def get_slot_row(self, slot_name): |
|
239 """Get row containing given slot""" |
|
240 |
|
241 def get_slots(self, row_id): |
|
242 """Get ordered list of slots for given row ID""" |
|
243 |
|
244 def get_slots_width(self, device=None): |
|
245 """Get slots width for given or all device(s)""" |
|
246 |
|
247 def set_slot_width(self, slot_name, device, width): |
|
248 """Set slot width for given device""" |
|
249 |
|
250 def get_slot_configuration(self, slot_name): |
|
251 """Get slot configuration for given slot""" |
|
252 |
|
253 def delete_slot(self, slot_name): |
|
254 """Delete template slot""" |
|
255 |
|
256 |
|
257 # class IPortalPortletsConfiguration(Interface): |
|
258 # """Portal template portlets configuration interface""" |
|
259 # |
|
260 portlet_config = PersistentDict(title="Portlet configuration", |
|
261 key_type=TextLine(), # slot name |
|
262 value_type=PersistentDict(key_type=Int(min=0), # portlet position inside slot |
|
263 value_type=Object(schema=IPortletConfiguration)), |
|
264 required=False) |
|
265 |
|
266 def add_portlet(self, portlet_name, slot_name): |
|
267 """Add portlet to givben slot""" |
|
268 |
|
269 def set_portlet_order(self, order): |
|
270 """Set template portlets order""" |
|
271 |
|
272 def get_portlet_configuration(self, slot_name, position): |
|
273 """Get portlet configuration for given slot""" |
|
274 |
|
275 def delete_portlet(self, slot_name, position): |
|
276 """Delete template portlet""" |
|
277 |
|
278 |
|
279 class IPortalTemplate(IAttributeAnnotatable): |
|
280 """Portal template interface |
|
281 |
|
282 A portal template is a named utility providing a name and a set of slots. |
|
283 """ |
|
284 |
|
285 name = TextLine(title=_("Template name"), |
|
286 description=_("Two registered templates can't share the same name..."), |
|
287 required=True) |
|
288 |
|
289 |
|
290 class IPortalWfTemplate(IWorkflowManagedContent): |
|
291 """Workflow managed portal template interface""" |
|
292 |
|
293 |
|
294 class IPortalTemplateContainer(IContainer, IAttributeAnnotatable): |
|
295 """Portal template container interface""" |
|
296 |
|
297 contains(IPortalTemplate) |
|
298 |
|
299 |
|
300 class IPortalTemplateContainerConfiguration(Interface): |
|
301 """Portal templates container configuration""" |
|
302 |
|
303 selected_portlets = List(title=_("Selected portlets"), |
|
304 description=_("These portlets will be directly available in templates configuration " |
|
305 "page toolbar"), |
|
306 value_type=Choice(vocabulary="PyAMS portal portlets"), |
|
307 required=False) |
|
308 |
|
309 |
|
310 class IPortalTemplateRenderer(IContentProvider): |
|
311 """Portal template renderer |
|
312 |
|
313 A portal template renderer should be implemented as an adapter for a context, a request |
|
314 and a template |
|
315 """ |
|
316 |
|
317 |
|
318 class IPortalPage(Interface): |
|
319 """Portal page interface |
|
320 |
|
321 The page is the highest configuration level. |
|
322 It defines which template is used (a shared or local one), which gives |
|
323 the slots list. |
|
324 """ |
|
325 |
|
326 can_inherit = Attribute("Can inherit parent template?") |
|
327 |
|
328 inherit_parent = Bool(title=_("Inherit parent template?"), |
|
329 description=_("Should we reuse parent template?"), |
|
330 required=True, |
|
331 default=True) |
|
332 |
|
333 use_local_template = Bool(title=_("Use local template?"), |
|
334 description=_("If 'yes', you can define a custom local template instead of " |
|
335 "a shared template"), |
|
336 required=True, |
|
337 default=False) |
|
338 |
|
339 shared_template = Choice(title=_("Page template"), |
|
340 description=_("Template used for this page"), |
|
341 vocabulary='PyAMS portal templates', |
|
342 required=False) |
|
343 |
|
344 @invariant |
|
345 def check_template(self): |
|
346 if not (self.use_local_template or self.shared_template): |
|
347 raise Invalid(_("You must choose to use a local template or select a shared one!")) |
|
348 |
|
349 local_template = Object(title=_("Local template"), |
|
350 schema=IPortalWfTemplate, |
|
351 required=False) |
|
352 |
|
353 template = Attribute("Used template") |
|
354 |
|
355 |
|
356 class IPortalContext(IAttributeAnnotatable): |
|
357 """Portal context marker interface""" |