diff --git a/CHANGES.rst b/CHANGES.rst index 024fbade..1ae55d91 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,12 @@ Changelog - Fix rss feed image selection, now it uses the correct field for preview_image. [mamico] - +- Handle sort_on also when using AdvancedQuery. + [cekk] +- Remove z3c.jbot compatibility and customize templates in standard-way. + [cekk] +- Force indexing subjects in SearchableText with ICategorization to keep the old Plone functionality (remove this when the official pr is merged). + [cekk] 5.5.10 (2025-05-09) ------------------- diff --git a/setup.py b/setup.py index 808846c9..8035362f 100644 --- a/setup.py +++ b/setup.py @@ -62,7 +62,6 @@ "plone.restapi>=9.6.0", "Products.PortalTransforms>=3.2.0", "collective.volto.sitesettings", - "z3c.jbot", ], extras_require={ "advancedquery": [ diff --git a/src/redturtle/volto/__init__.py b/src/redturtle/volto/__init__.py index 86397e01..ae368d9f 100644 --- a/src/redturtle/volto/__init__.py +++ b/src/redturtle/volto/__init__.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- """Init and utils.""" from plone.app.content.browser.vocabulary import PERMISSIONS +from plone.app.dexterity.behaviors.metadata import ICategorization +from plone.app.dexterity.textindexer import utils from plone.folder.nogopip import GopipIndex from Products.ZCatalog.Catalog import Catalog from redturtle.volto.catalogplan import Catalog_sorted_search_indexes @@ -12,10 +14,11 @@ logger = logging.getLogger(__name__) - - _ = MessageFactory("redturtle.volto") +# Index also subjects in SearchableText. +utils.searchable(ICategorization, "subjects") + PERMISSIONS["plone.app.vocabularies.Keywords"] = "View" # CATALOG PATCHES diff --git a/src/redturtle/volto/browser/configure.zcml b/src/redturtle/volto/browser/configure.zcml index 126261bf..8b294b73 100644 --- a/src/redturtle/volto/browser/configure.zcml +++ b/src/redturtle/volto/browser/configure.zcml @@ -5,15 +5,6 @@ i18n_domain="redturtle.volto" > - - - + + + - diff --git a/src/redturtle/volto/browser/overrides/plone.app.contenttypes.browser.templates.document.pt b/src/redturtle/volto/browser/templates/document.pt similarity index 100% rename from src/redturtle/volto/browser/overrides/plone.app.contenttypes.browser.templates.document.pt rename to src/redturtle/volto/browser/templates/document.pt diff --git a/src/redturtle/volto/browser/overrides/plone.volto.browser.voltobackendwarning.pt b/src/redturtle/volto/browser/templates/voltobackendwarning.pt similarity index 97% rename from src/redturtle/volto/browser/overrides/plone.volto.browser.voltobackendwarning.pt rename to src/redturtle/volto/browser/templates/voltobackendwarning.pt index fc3462ed..ead63e9e 100644 --- a/src/redturtle/volto/browser/overrides/plone.volto.browser.voltobackendwarning.pt +++ b/src/redturtle/volto/browser/templates/voltobackendwarning.pt @@ -1,3 +1,2 @@ - diff --git a/src/redturtle/volto/interfaces.py b/src/redturtle/volto/interfaces.py index 54d377f1..ee048649 100644 --- a/src/redturtle/volto/interfaces.py +++ b/src/redturtle/volto/interfaces.py @@ -1,16 +1,16 @@ # -*- coding: utf-8 -*- -# from zope.publisher.interfaces.browser import IDefaultBrowserLayer from plone.app.contenttypes.interfaces import ( IPloneAppContenttypesLayer as IDefaultBrowserLayer, ) from plone.dexterity.interfaces import IDexterityContent from plone.restapi.controlpanels.interfaces import IControlpanel +from plone.volto.interfaces import IPloneVoltoCoreLayer from redturtle.volto import _ from zope.interface import Interface from zope.schema import Bool -class IRedturtleVoltoLayer(IDefaultBrowserLayer): +class IRedturtleVoltoLayer(IDefaultBrowserLayer, IPloneVoltoCoreLayer): """Marker interface that defines a browser layer.""" diff --git a/src/redturtle/volto/restapi/services/search/get.py b/src/redturtle/volto/restapi/services/search/get.py index 5ba222f7..f0b27223 100644 --- a/src/redturtle/volto/restapi/services/search/get.py +++ b/src/redturtle/volto/restapi/services/search/get.py @@ -44,8 +44,6 @@ def get_indexes_mapping(self): def is_advanced_query(self, query): if not query: return False - if query.get("sort_on", None): - return False if query.get("SimpleQuery", None): return False custom_ranking_enabled = api.portal.get_registry_record( @@ -76,11 +74,25 @@ def search(self, query=None): # TODO: mettere i parametri di ranking in registry # XXX: il default sul subject ha senso ? (probabilmente no), rivedere eventualmente anche i test term = query.get("SearchableText") - rs = RankByQueries_Sum( - (Eq("Subject", term), 16), - (Eq("Title", term), 8), - (Eq("Description", term), 6), - ) + + sort_on = query.get("sort_on", "") + if sort_on: + sort_order = query.get("sort_order", "") + if not sort_order: + if sort_on in ["Date", "effective"]: + sort_order = "desc" + else: + sort_order = "asc" + if sort_order == "reverse": + sort_order = "desc" + rs = (query["sort_on"], sort_order) + else: + # use custom ranking + rs = RankByQueries_Sum( + (Eq("Subject", term), 16), + (Eq("Title", term), 8), + (Eq("Description", term), 6), + ) lazy_resultset = self.catalog.evalAdvancedQuery( # Eq("SearchableText", term), (rs,), **query And(*queries), diff --git a/src/redturtle/volto/tests/test_advancedsearch.py b/src/redturtle/volto/tests/test_advancedsearch.py index abf58c55..5b0268f3 100644 --- a/src/redturtle/volto/tests/test_advancedsearch.py +++ b/src/redturtle/volto/tests/test_advancedsearch.py @@ -41,7 +41,7 @@ def setUp(self): type="Document", id="d1", title="document", - description="Foo document", + description="Document with subject", subject=["foo", "bar"], ) # 3rd for "Foo" (title + searchableText) @@ -84,7 +84,7 @@ def test_simplesearch(self): self.assertEqual(result["items_total"], 3) # explain why the order is different from the one in the test above self.assertEqual( - ["f1", "d1", "e1"], [item["@id"].split("/")[-1] for item in result["items"]] + ["f1", "e1", "d1"], [item["@id"].split("/")[-1] for item in result["items"]] ) def test_search_foo(self): @@ -163,7 +163,7 @@ def test_search_by_not_handled_index_type_return_standard_order(self): result = response.json() self.assertEqual(result["items_total"], 3) self.assertEqual( - ["f1", "d1", "e1"], [item["@id"].split("/")[-1] for item in result["items"]] + ["f1", "e1", "d1"], [item["@id"].split("/")[-1] for item in result["items"]] ) def test_search_no_query(self): @@ -195,7 +195,31 @@ def test_search_ignore_non_existent_indexes_and_return_custom_order_if_possible( result = response.json() self.assertEqual(result["items_total"], 3) self.assertEqual( - ["f1", "d1", "e1"], [item["@id"].split("/")[-1] for item in result["items"]] + ["f1", "e1", "d1"], [item["@id"].split("/")[-1] for item in result["items"]] + ) + + def test_search_use_sort_on_if_in_query_and_ignore_custom_order( + self, + ): + response = self.api_session.get( + "/@search", params={"SearchableText": "foo", "sort_on": "sortable_title"} + ) + result = response.json() + self.assertEqual(result["items_total"], 3) + self.assertEqual( + ["d1", "e1", "f1"], + [item["@id"].split("/")[-1] for item in result["items"]], + ) + + # now repeat query with no sort_on and have custom order + response = self.api_session.get( + "/@search", + params={"SearchableText": "foo"}, + ) + result = response.json() + self.assertEqual(result["items_total"], 3) + self.assertEqual( + ["d1", "f1", "e1"], [item["@id"].split("/")[-1] for item in result["items"]] ) @@ -207,7 +231,7 @@ def test_by_default_flag_is_disabled(self): self.assertEqual(result["items_total"], 3) # explain why the order is different from the one in the test above self.assertEqual( - ["f1", "d1", "e1"], [item["@id"].split("/")[-1] for item in result["items"]] + ["f1", "e1", "d1"], [item["@id"].split("/")[-1] for item in result["items"]] ) def test_enabling_flag_return_custom_order(self): diff --git a/test_plone60.cfg b/test_plone60.cfg index c0e79122..3c739e00 100644 --- a/test_plone60.cfg +++ b/test_plone60.cfg @@ -6,18 +6,3 @@ extends = base.cfg [versions] -docutils = - -# Added by buildout at 2023-03-10 11:55:21.122842 -Products.AdvancedQuery = 4.2.1 -createcoverage = 1.5 -dm.plone.advancedquery = 1.0 -flake8 = 6.0.0 -mccabe = 0.7.0 -plone.recipe.codeanalysis = 3.0.1 -pycodestyle = 2.10.0 -pyflakes = 3.0.1 -docutils = 0.21.2 -plone.stringinterp = 2.0.0 -# plone.restapi >= 9.6.1 don't put subjects into SearchableText (to investigate) -plone.restapi = 9.6.0