Repository: plone/plone.restapi (language: python)

Issue:
Navigation: nav_title is never applied to navigation items



Discussion / hints:

Fix patch:
diff --git a/news/1169.bugfix b/news/1169.bugfix
new file mode 100644
index 0000000000..0d3df90cb3
--- /dev/null
+++ b/news/1169.bugfix
@@ -0,0 +1,2 @@
+Fix navigation service not using nav_title metadata.
+[ericof]
diff --git a/src/plone/restapi/services/navigation/get.py b/src/plone/restapi/services/navigation/get.py
index c9b6b6a7f3..8d3d2ca5d9 100644
--- a/src/plone/restapi/services/navigation/get.py
+++ b/src/plone/restapi/services/navigation/get.py
@@ -174,9 +174,8 @@ def navtree(self):
                 "review_state": json_compatible(brain.review_state),
                 "use_view_action_in_listings": brain.portal_type in types_using_view,
             }
-
-            if brain.get("nav_title", False):
-                entry.update({"title": brain["nav_title"]})
+            if "nav_title" in brain and brain.nav_title:
+                entry.update({"title": brain.nav_title})
 
             self.customize_entry(entry, brain)
             ret[brain_parent_path].append(entry)


Test patch:
diff --git a/src/plone/restapi/profiles/testing/catalog.xml b/src/plone/restapi/profiles/testing/catalog.xml
new file mode 100644
index 0000000000..cb243018d5
--- /dev/null
+++ b/src/plone/restapi/profiles/testing/catalog.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<object name="portal_catalog">
+  <column value="nav_title" />
+</object>
diff --git a/src/plone/restapi/tests/dxtypes.py b/src/plone/restapi/tests/dxtypes.py
index a71d5fd9da..493801524b 100644
--- a/src/plone/restapi/tests/dxtypes.py
+++ b/src/plone/restapi/tests/dxtypes.py
@@ -312,6 +312,8 @@ class DXTestDocument(Item):
 class ITestBehavior(model.Schema):
 
     test_behavior_field = schema.TextLine(required=False)
+    # Add nav_title to test if it gets substituted in Navigation service
+    nav_title = schema.TextLine(required=False)
 
 
 @provider(IFormFieldProvider)
diff --git a/src/plone/restapi/tests/http-examples/link.resp b/src/plone/restapi/tests/http-examples/link.resp
index 9a7c04edbb..7e57f8c088 100644
--- a/src/plone/restapi/tests/http-examples/link.resp
+++ b/src/plone/restapi/tests/http-examples/link.resp
@@ -54,7 +54,7 @@ Content-Type: application/json
     "description": "Congratulations! You have successfully installed Plone.", 
     "title": "Welcome to Plone"
   }, 
-  "remoteUrl": "http://localhost:55001/plone",
+  "remoteUrl": "http://localhost:55001/plone", 
   "review_state": "private", 
   "rights": "", 
   "subjects": [], 
diff --git a/src/plone/restapi/tests/test_services_navigation.py b/src/plone/restapi/tests/test_services_navigation.py
index 74c08eee51..89092d17ff 100644
--- a/src/plone/restapi/tests/test_services_navigation.py
+++ b/src/plone/restapi/tests/test_services_navigation.py
@@ -3,8 +3,11 @@
 from plone.app.testing import SITE_OWNER_PASSWORD
 from plone.app.testing import TEST_USER_ID
 from plone.dexterity.utils import createContentInContainer
+from plone.registry.interfaces import IRegistry
 from plone.restapi.testing import PLONE_RESTAPI_DX_FUNCTIONAL_TESTING
 from plone.restapi.testing import RelativeSession
+from Products.CMFPlone.interfaces.controlpanel import INavigationSchema
+from zope.component import getUtility
 
 import transaction
 import unittest
@@ -207,3 +210,27 @@ def test_navigation_sorting(self):
                 "/folder/doc1",
             ],
         )
+
+    def test_use_nav_title_when_available_and_set(self):
+        registry = getUtility(IRegistry)
+        settings = registry.forInterface(INavigationSchema, prefix="plone")
+        displayed_types = settings.displayed_types
+        settings.displayed_types = tuple(list(displayed_types) + ["DXTestDocument"])
+
+        title = "Example Document"
+        nav_title = "Fancy title"
+
+        createContentInContainer(
+            self.folder,
+            "DXTestDocument",
+            id="example-dx-document",
+            title=title,
+            nav_title=nav_title,
+        )
+        transaction.commit()
+
+        response = self.api_session.get(
+            "/folder/@navigation", params={"expand.navigation.depth": 2}
+        )
+
+        self.assertEqual(response.json()["items"][1]["items"][-1]["title"], nav_title)