--- a/src/pyams_content/features/search/__init__.py Tue Dec 01 09:19:16 2020 +0100
+++ b/src/pyams_content/features/search/__init__.py Mon Jan 11 16:45:22 2021 +0100
@@ -64,12 +64,15 @@
return True
def get_results(self, context, sort_index=None, reverse=None, limit=None,
- start=0, length=None, ignore_cache=False, get_count=False, request=None):
+ start=0, length=None, ignore_cache=False, get_count=False, request=None,
+ aggregates=None):
if not ignore_cache:
- request = check_request()
+ if request is None:
+ request = check_request()
ignore_cache = bool(request.params)
return super(SearchFolder, self).get_results(context, sort_index, reverse, limit, start,
- length, ignore_cache, get_count, request)
+ length, ignore_cache, get_count, request,
+ aggregates)
@adapter_config(context=ISearchFolder, provides=IFormContextPermissionChecker)
@@ -143,3 +146,15 @@
Contains(index, ' and '.join((w + '*'
for w in fulltext.split()))))
yield Or(*query_params)
+
+
+@adapter_config(name='content_type', context=SearchFolderQuery, provides=IViewUserQuery)
+class SearchFolderContentTypeQuery(ContextAdapter):
+ """Search folder content-type query"""
+
+ @staticmethod
+ def get_user_params(request):
+ content_type = request.params.get('content_type')
+ if content_type:
+ catalog = get_utility(ICatalog)
+ yield Eq(catalog['content_type'], content_type)
--- a/src/pyams_content/features/search/portlet/__init__.py Tue Dec 01 09:19:16 2020 +0100
+++ b/src/pyams_content/features/search/portlet/__init__.py Mon Jan 11 16:45:22 2021 +0100
@@ -19,8 +19,10 @@
from pyams_content import _
from pyams_content.features.search import ISearchFolder
-from pyams_content.features.search.portlet.interfaces import ISearchResultsPortletSettings
+from pyams_content.features.search.portlet.interfaces import IAggregatedPortletRenderer, \
+ ISearchResultsPortletSettings
from pyams_content.shared.view.interfaces import RELEVANCE_ORDER, VISIBLE_PUBLICATION_DATE_ORDER
+from pyams_portal.interfaces import IPortletRendererSettings
from pyams_portal.portlet import Portlet, PortletSettings, portlet_config
from pyams_utils.factory import factory_config
from pyams_utils.interfaces import VIEW_PERMISSION
@@ -44,8 +46,7 @@
params = request.params
return params.get('user_search', '').strip()
- @staticmethod
- def _get_items(request=None, start=0, length=10, limit=None, ignore_cache=False):
+ def _get_items(self, request=None, start=0, length=10, limit=None, ignore_cache=False):
context = get_parent(request.context, ISearchFolder)
if context is None:
raise StopIteration
@@ -57,6 +58,11 @@
if (order_by == RELEVANCE_ORDER) and \
not SearchResultsPortletSettings.has_user_query(request):
request.GET['order_by'] = order_by = VISIBLE_PUBLICATION_DATE_ORDER
+ renderer_settings = IPortletRendererSettings(self)
+ if IAggregatedPortletRenderer.providedBy(renderer_settings):
+ aggregates = renderer_settings.aggregates
+ else:
+ aggregates = {}
yield from context.get_results(context, order_by,
reverse=order_by != RELEVANCE_ORDER,
limit=limit,
@@ -64,19 +70,20 @@
length=int(length),
ignore_cache=ignore_cache,
get_count=True,
- request=request)
+ request=request,
+ aggregates=aggregates)
def get_items(self, request=None, start=0, length=10, limit=None, ignore_cache=False):
if not (self.allow_empty_query or self.has_user_query(request)):
- yield from iter(((), 0), )
+ yield from iter(((), 0, {}), )
else:
check, items = tee(
- SearchResultsPortletSettings._get_items(request, start, length, limit,
- ignore_cache))
+ self._get_items(request, start, length, limit,
+ ignore_cache))
try:
next(check)
except StopIteration:
- yield from iter(((), 0), )
+ yield from iter(((), 0, {}), )
else:
yield from items
--- a/src/pyams_content/features/search/portlet/interfaces.py Tue Dec 01 09:19:16 2020 +0100
+++ b/src/pyams_content/features/search/portlet/interfaces.py Mon Jan 11 16:45:22 2021 +0100
@@ -10,15 +10,24 @@
# FOR A PARTICULAR PURPOSE.
#
-__docformat__ = 'restructuredtext'
-
+from zope.interface import Attribute, Interface
from zope.schema import Bool
-from pyams_content import _
from pyams_i18n.schema import I18nTextLineField
from pyams_portal.interfaces import IPortletSettings
+__docformat__ = 'restructuredtext'
+
+from pyams_content import _
+
+
+class IAggregatedPortletRenderer(Interface):
+ """Search results portlet renderer with aggregations"""
+
+ aggregates = Attribute("Search results aggregates")
+
+
class ISearchResultsPortletSettings(IPortletSettings):
"""Search results portlet settings"""
--- a/src/pyams_content/features/search/portlet/zmi/templates/search-preview.pt Tue Dec 01 09:19:16 2020 +0100
+++ b/src/pyams_content/features/search/portlet/zmi/templates/search-preview.pt Mon Jan 11 16:45:22 2021 +0100
@@ -1,6 +1,6 @@
<div class="padding-x-5" i18n:domain="pyams_content"
tal:define="settings view.settings; global count 0;
- (items, count) settings.get_items(request, limit=10, ignore_cache=True);">
+ (items, count, aggregations) settings.get_items(request, limit=10, ignore_cache=True);">
<strong>${i18n:settings.title}</strong>
<div class="padding-x-10">
<i class="fa fa-fw fa-${'check-' if settings.allow_empty_query else ''}square-o"></i>
--- a/src/pyams_content/shared/view/__init__.py Tue Dec 01 09:19:16 2020 +0100
+++ b/src/pyams_content/shared/view/__init__.py Mon Jan 11 16:45:22 2021 +0100
@@ -111,8 +111,9 @@
return list(data_types)
def get_results(self, context, sort_index=None, reverse=None, limit=None,
- start=0, length=999, ignore_cache=False, get_count=False, request=None):
- results, count = _MARKER, 0
+ start=0, length=999, ignore_cache=False, get_count=False, request=None,
+ aggregates=None):
+ results, count, aggregations = _MARKER, 0, {}
if not ignore_cache:
# check for cache
views_cache = get_cache(VIEWS_CACHE_REGION, VIEWS_CACHE_NAME)
@@ -124,6 +125,7 @@
try:
results = views_cache.get_value(cache_key)
count = views_cache.get_value(cache_key + '::count')
+ aggregations = views_cache.get_value(cache_key + '::aggregations')
except KeyError:
pass
# Execute query
@@ -136,22 +138,25 @@
if not sort_index:
sort_index = self.order_by
# Get query results
- results, count = adapter.get_results(context,
- sort_index,
- reverse if reverse is not None else self.reversed_order,
- limit or self.limit,
- request=request)
+ results, count, aggregations = adapter.get_results(context,
+ sort_index,
+ reverse if reverse is not None
+ else self.reversed_order,
+ limit or self.limit,
+ request=request,
+ aggregates=aggregates)
count = min(count, limit or self.limit or 999)
cache, results = tee(islice(results, start, start + length))
if not ignore_cache:
intids = get_utility(IIntIds)
views_cache.set_value(cache_key, [intids.queryId(item) for item in cache])
views_cache.set_value(cache_key + '::count', count)
+ views_cache.set_value(cache_key + '::aggregations', aggregations)
logger.debug("Storing view items to cache key {0}".format(cache_key))
else:
results = CatalogResultSet(results)
logger.debug("Retrieving view items from cache key {0}".format(cache_key))
- return (results, count) if get_count else results
+ return (results, count, aggregations) if get_count else results
register_content_type(WfView, shared_content=False)
@@ -215,7 +220,8 @@
filters &= Any(catalog['data_type'], data_types)
return params
- def get_results(self, context, sort_index, reverse, limit, request=None):
+ def get_results(self, context, sort_index, reverse, limit,
+ request=None, aggregates=None):
view = self.context
catalog = get_utility(ICatalog)
registry = get_current_registry()
@@ -235,7 +241,7 @@
for name, adapter in sorted(registry.getAdapters((view,), IViewQueryFilterExtension),
key=lambda x: x[1].weight):
items = adapter.filter(context, items, request)
- return unique_iter(items), total_count
+ return unique_iter(items), total_count, {}
@subscriber(IObjectModifiedEvent, context_selector=IWfView)
--- a/src/pyams_content/shared/view/interfaces.py Tue Dec 01 09:19:16 2020 +0100
+++ b/src/pyams_content/shared/view/interfaces.py Mon Jan 11 16:45:22 2021 +0100
@@ -154,7 +154,8 @@
def get_params(self, context, request=None):
"""Get static view query params"""
- def get_results(self, context, sort_index, reverse, limit, request=None):
+ def get_results(self, context, sort_index, reverse, limit,
+ request=None, aggregates=None):
"""Get tuple of limited results and total results count"""