src/pyams_content/shared/view/portlet/__init__.py
changeset 783 e34cc04e9786
parent 691 773429b4a3ed
child 796 2ef3bacda742
--- a/src/pyams_content/shared/view/portlet/__init__.py	Mon Jul 02 17:10:37 2018 +0200
+++ b/src/pyams_content/shared/view/portlet/__init__.py	Mon Jul 02 17:11:41 2018 +0200
@@ -14,16 +14,21 @@
 
 
 # import standard library
+from itertools import islice
 
 # import interfaces
-from pyams_content.shared.view.portlet.interfaces import IViewItemsPortletSettings
+from pyams_content.shared.view.interfaces import IViewsMerger
+from pyams_content.shared.view.portlet.interfaces import IViewItemsPortletSettings, VIEW_DISPLAY_CONTEXT
 from pyams_utils.interfaces import VIEW_PERMISSION
+from pyams_utils.interfaces.url import DISPLAY_CONTEXT
 
 # import packages
 from pyams_content.workflow import PUBLISHED_STATES
 from pyams_portal.portlet import PortletSettings, portlet_config, Portlet
 from pyams_sequence.utility import get_sequence_target
 from pyams_utils.factory import factory_config
+from pyams_utils.list import unique_iter
+from pyams_utils.request import check_request
 from zope.interface import implementer
 from zope.schema.fieldproperty import FieldProperty
 
@@ -38,16 +43,37 @@
 class ViewItemsPortletSettings(PortletSettings):
     """View items portlet settings"""
 
-    view = FieldProperty(IViewItemsPortletSettings['view'])
+    views = FieldProperty(IViewItemsPortletSettings['views'])
+    views_context = FieldProperty(IViewItemsPortletSettings['views_context'])
+    views_merge_mode = FieldProperty(IViewItemsPortletSettings['views_merge_mode'])
+    limit = FieldProperty(IViewItemsPortletSettings['limit'])
+
+    def get_merger(self, request=None):
+        if request is None:
+            request = check_request()
+        return request.registry.queryUtility(IViewsMerger, name=self.views_merge_mode)
+
+    def get_views(self):
+        for oid in self.views or ():
+            view = get_sequence_target(oid, state=PUBLISHED_STATES)
+            if view is not None:
+                yield view
 
-    def get_view(self):
-        if self.view is not None:
-            return get_sequence_target(self.view, state=PUBLISHED_STATES)
-
-    def get_items(self, context):
-        view = self.get_view()
-        if view is not None:
-            return view.get_results(context)
+    def get_items(self, request=None):
+        if request is None:
+            request = check_request()
+        if self.views_context == VIEW_DISPLAY_CONTEXT:
+            context = request.annotations.get(DISPLAY_CONTEXT, request.root)
+        else:
+            context = request.context
+        if len(self.views or ()) < 2:  # single view
+            for view in self.get_views():
+                if view is not None:
+                    yield from islice(view.get_results(context), self.limit)
+        else:  # several views merged together
+            merger = self.get_merger(request)
+            if merger is not None:
+                yield from islice(unique_iter(merger.get_results(self.get_views(), context)), self.limit)
 
 
 @portlet_config(permission=VIEW_PERMISSION)