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