9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
10 # FOR A PARTICULAR PURPOSE. |
10 # FOR A PARTICULAR PURPOSE. |
11 # |
11 # |
12 |
12 |
13 import logging |
13 import logging |
14 logger = logging.getLogger('PyAMS (portal)') |
|
15 |
14 |
16 import venusian |
15 import venusian |
17 from persistent import Persistent |
16 from persistent import Persistent |
18 from persistent.mapping import PersistentMapping |
17 from persistent.mapping import PersistentMapping |
19 from pyramid.exceptions import ConfigurationError |
18 from pyramid.exceptions import ConfigurationError |
28 from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary |
27 from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary |
29 from zope.traversing.interfaces import ITraversable |
28 from zope.traversing.interfaces import ITraversable |
30 |
29 |
31 from pyams_cache.beaker import get_cache |
30 from pyams_cache.beaker import get_cache |
32 from pyams_form.interfaces.form import IFormContextPermissionChecker |
31 from pyams_form.interfaces.form import IFormContextPermissionChecker |
33 from pyams_portal.interfaces import IPortalContext, IPortalPage, IPortalPortletsConfiguration, IPortalTemplate, \ |
32 from pyams_portal.interfaces import IPortalContext, IPortalPage, IPortalPortletsConfiguration, \ |
34 IPortalTemplateConfiguration, IPortlet, IPortletConfiguration, IPortletPreviewer, IPortletRenderer, \ |
33 IPortalTemplate, IPortalTemplateConfiguration, IPortlet, IPortletConfiguration, \ |
35 IPortletRendererSettings, IPortletSettings, MANAGE_TEMPLATE_PERMISSION, PORTLET_RENDERER_SETTINGS_KEY, PREVIEW_MODE |
34 IPortletPreviewer, IPortletRenderer, IPortletRendererSettings, IPortletSettings, \ |
36 from pyams_utils.adapter import ContextAdapter, adapter_config, get_adapter_weight, get_annotation_adapter |
35 MANAGE_TEMPLATE_PERMISSION, PORTLET_RENDERER_SETTINGS_KEY, PREVIEW_MODE |
37 from pyams_utils.factory import get_object_factory, is_interface, factory_config |
36 from pyams_utils.adapter import ContextAdapter, adapter_config, get_adapter_weight, \ |
|
37 get_annotation_adapter |
|
38 from pyams_utils.factory import factory_config, get_object_factory, is_interface |
38 from pyams_utils.interfaces import ICacheKeyValue |
39 from pyams_utils.interfaces import ICacheKeyValue |
39 from pyams_utils.interfaces.url import DISPLAY_CONTEXT |
40 from pyams_utils.interfaces.url import DISPLAY_CONTEXT |
40 from pyams_utils.registry import get_global_registry |
41 from pyams_utils.registry import get_global_registry |
41 from pyams_utils.request import check_request |
42 from pyams_utils.request import check_request |
42 from pyams_utils.vocabulary import vocabulary_config |
43 from pyams_utils.vocabulary import vocabulary_config |
43 from pyams_viewlet.viewlet import ViewContentProvider |
44 from pyams_viewlet.viewlet import ViewContentProvider |
44 |
45 |
|
46 |
45 __docformat__ = 'restructuredtext' |
47 __docformat__ = 'restructuredtext' |
|
48 |
|
49 from pyams_portal import _ |
|
50 |
|
51 |
|
52 logger = logging.getLogger('PyAMS (portal)') |
46 |
53 |
47 |
54 |
48 # |
55 # |
49 # Portlets utilities |
56 # Portlets utilities |
50 # |
57 # |
88 else: |
95 else: |
89 factory = None |
96 factory = None |
90 component = ob |
97 component = ob |
91 |
98 |
92 config = context.config.with_package(info.module) |
99 config = context.config.with_package(info.module) |
93 logger.debug("Registering portlet {0} named '{1}'".format(str(component) if component else str(factory), |
100 logger.debug("Registering portlet {0} named '{1}'".format( |
94 name)) |
101 str(component) if component else str(factory), name)) |
95 config.registry.registerUtility(component=component, factory=factory, |
102 config.registry.registerUtility(component=component, factory=factory, |
96 provided=IPortlet, name=name) |
103 provided=IPortlet, name=name) |
97 |
104 |
98 info = self.venusian.attach(wrapped, callback, category='pyams_portal', |
105 info = self.venusian.attach(wrapped, callback, category='pyams_portal', |
99 depth=depth + 1) |
106 depth=depth + 1) |
128 class PortletContentProvider(ViewContentProvider): |
135 class PortletContentProvider(ViewContentProvider): |
129 """Base portlet content provider""" |
136 """Base portlet content provider""" |
130 |
137 |
131 def __init__(self, context, request, view, settings): |
138 def __init__(self, context, request, view, settings): |
132 super(PortletContentProvider, self).__init__(context, request, view) |
139 super(PortletContentProvider, self).__init__(context, request, view) |
133 self.portlet = request.registry.queryUtility(IPortlet, name=settings.configuration.portlet_name) |
140 self.portlet = request.registry.queryUtility(IPortlet, |
|
141 name=settings.configuration.portlet_name) |
134 self.settings = settings |
142 self.settings = settings |
135 |
143 |
136 def render(self): |
144 def render(self): |
137 if self.portlet is None: |
145 if self.portlet is None: |
138 return '' |
146 return '' |
139 if self.portlet.permission and not self.request.has_permission(self.portlet.permission): |
147 if self.portlet.permission and not self.request.has_permission(self.portlet.permission): |
140 return '' |
148 return '' |
141 return super(PortletContentProvider, self).render() |
149 return super(PortletContentProvider, self).render() |
|
150 |
|
151 |
|
152 PREVIEW_PREFIX = '''<div class="padding-x-5 text-info"> |
|
153 <span>{label}</span> |
|
154 {renderer} |
|
155 </div>''' |
142 |
156 |
143 |
157 |
144 @implementer(IPortletPreviewer) |
158 @implementer(IPortletPreviewer) |
145 class PortletPreviewer(PortletContentProvider): |
159 class PortletPreviewer(PortletContentProvider): |
146 """Portlet previewer adapter""" |
160 """Portlet previewer adapter""" |
157 |
171 |
158 def render(self): |
172 def render(self): |
159 if self.settings.renderer == 'hidden': |
173 if self.settings.renderer == 'hidden': |
160 return render('templates/portlet-hidden.pt', {}, request=self.request) |
174 return render('templates/portlet-hidden.pt', {}, request=self.request) |
161 else: |
175 else: |
162 return super(PortletPreviewer, self).render() |
176 result = super(PortletPreviewer, self).render() |
|
177 settings = self.settings |
|
178 if settings.renderer: |
|
179 renderer = settings.get_renderer() |
|
180 translate = self.request.localizer.translate |
|
181 result = PREVIEW_PREFIX.format(label=translate(_("Renderer:")), |
|
182 renderer=translate(renderer.label)) + result |
|
183 return result |
163 |
184 |
164 |
185 |
165 PORTLETS_CACHE_REGION = 'portlets' |
186 PORTLETS_CACHE_REGION = 'portlets' |
166 PORTLETS_CACHE_NAME = 'PyAMS::portlet' |
187 PORTLETS_CACHE_NAME = 'PyAMS::portlet' |
167 |
188 |
208 lang=self.request.locale_name) |
229 lang=self.request.locale_name) |
209 else: |
230 else: |
210 return PORTLETS_CACHE_DISPLAY_CONTEXT_KEY.format(portlet=ICacheKeyValue(self.settings), |
231 return PORTLETS_CACHE_DISPLAY_CONTEXT_KEY.format(portlet=ICacheKeyValue(self.settings), |
211 hostname=self.request.host, |
232 hostname=self.request.host, |
212 context=ICacheKeyValue(self.context), |
233 context=ICacheKeyValue(self.context), |
213 display=ICacheKeyValue(display_context), |
234 display=ICacheKeyValue( |
|
235 display_context), |
214 lang=self.request.locale_name) |
236 lang=self.request.locale_name) |
215 |
237 |
216 def render(self): |
238 def render(self): |
217 preview_mode = self.request.annotations.get(PREVIEW_MODE, False) |
239 preview_mode = self.request.annotations.get(PREVIEW_MODE, False) |
218 if preview_mode or not self.use_portlets_cache: |
240 if preview_mode or not self.use_portlets_cache: |
240 |
262 |
241 def __init__(self, context): |
263 def __init__(self, context): |
242 request = check_request() |
264 request = check_request() |
243 translate = request.localizer.translate |
265 translate = request.localizer.translate |
244 terms = [SimpleTerm(name, title=translate(adapter.label)) |
266 terms = [SimpleTerm(name, title=translate(adapter.label)) |
245 for name, adapter in sorted(request.registry.getAdapters((request.root, request, request, context), |
267 for name, adapter in sorted(request.registry.getAdapters((request.root, request, |
|
268 request, context), |
246 IPortletRenderer), |
269 IPortletRenderer), |
247 key=get_adapter_weight)] |
270 key=get_adapter_weight)] |
248 super(PortletRenderersVocabulary, self).__init__(terms) |
271 super(PortletRenderersVocabulary, self).__init__(terms) |
249 |
272 |
250 |
273 |
283 def renderer(self, value): |
306 def renderer(self, value): |
284 value = value or '' |
307 value = value or '' |
285 if value == self._renderer: |
308 if value == self._renderer: |
286 return |
309 return |
287 request = check_request() |
310 request = check_request() |
288 renderer = request.registry.queryMultiAdapter((request.root, request, request, self), IPortletRenderer, |
311 renderer = request.registry.queryMultiAdapter((request.root, request, request, self), |
289 name=self._renderer) |
312 IPortletRenderer, name=self._renderer) |
290 if (renderer is not None) and (renderer.target_interface is not None): |
313 if (renderer is not None) and (renderer.target_interface is not None): |
291 noLongerProvides(self, renderer.target_interface) |
314 noLongerProvides(self, renderer.target_interface) |
292 self._renderer = value |
315 self._renderer = value |
293 renderer = request.registry.queryMultiAdapter((request.root, request, request, self), IPortletRenderer, |
316 renderer = request.registry.queryMultiAdapter((request.root, request, request, self), |
294 name=self._renderer) |
317 IPortletRenderer, name=self._renderer) |
295 if (renderer is not None) and (renderer.target_interface is not None): |
318 if (renderer is not None) and (renderer.target_interface is not None): |
296 alsoProvides(self, renderer.target_interface) |
319 alsoProvides(self, renderer.target_interface) |
297 |
320 |
298 def get_renderer(self, request=None): |
321 def get_renderer(self, request=None): |
299 if request is None: |
322 if request is None: |
300 request = check_request() |
323 request = check_request() |
301 return request.registry.queryMultiAdapter((request.root, request, request, self), IPortletRenderer, |
324 return request.registry.queryMultiAdapter((request.root, request, request, self), |
302 name=self._renderer) |
325 IPortletRenderer, name=self._renderer) |
303 |
326 |
304 @property |
327 @property |
305 def configuration(self): |
328 def configuration(self): |
306 return self.__parent__ |
329 return self.__parent__ |
307 |
330 |
383 parent = self.__parent__ |
406 parent = self.__parent__ |
384 if IPortalTemplate.providedBy(parent): |
407 if IPortalTemplate.providedBy(parent): |
385 return parent |
408 return parent |
386 while True: |
409 while True: |
387 if IPortalContext.providedBy(parent): |
410 if IPortalContext.providedBy(parent): |
388 configuration = IPortalPortletsConfiguration(parent).get_portlet_configuration(self.portlet_id) |
411 configuration = IPortalPortletsConfiguration(parent).get_portlet_configuration( |
|
412 self.portlet_id) |
389 if not configuration.inherit_parent: |
413 if not configuration.inherit_parent: |
390 return parent |
414 return parent |
391 page = IPortalPage(parent) |
415 page = IPortalPage(parent) |
392 if not page.inherit_parent: |
416 if not page.inherit_parent: |
393 break |
417 break |