Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a new @navtree REST API service #305

Open
wants to merge 4 commits into
base: quaive-app
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/osha/oira/services/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,13 @@
name="@tool-versions"
/>

<plone:service
method="GET"
factory=".navigation.NavigationService"
permission="zope2.View"
for="*"
layer="osha.oira.interfaces.IOSHAContentSkinLayer"
name="@navtree"
/>

</configure>
67 changes: 67 additions & 0 deletions src/osha/oira/services/navigation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from plone import api
from plone.restapi.services import Service


class NavigationService(Service):
"""This JSON service reuses the navigation tile to serve through the
REST API the navigation tree of this context.

The nodes of the tree should be prepared to have a successful
JSON serialization.

This method removes the keys:

- brain (which is not serializable)
- parent (which will create a circular reference)

and renames some keys to match the plone.restapi standards:

- portal_type -> @type
- url -> @id

It also fixes the portal_type which is returned normalized
with a dash instead of a dot.
"""

def fix_node(self, node):
"""Prepare a node for serialization"""
banned_keys = [
"brain", # not serializable
"parent", # creates a circular reference
]
for key in banned_keys:
if key in node:
del node[key]

# Rename keys to match plone.restapi standards
mapping = {
"portal_type": "@type",
"url": "@id",
"children": "items",
}
for old_key, new_key in mapping.items():
if old_key in node:
node[new_key] = node.pop(old_key)

# Fix the portal_type
if "@type" in node:
node["@type"] = node["@type"].replace("-", ".")

# Recurse into children
if "items" in node:
for child in node["items"]:
self.fix_node(child)

return node

def reply(self):
"""We use the navtree tile to get the navigation tree,
but we have to fiddle with the nodes to have a proper serialization.
"""
navtree_tile = api.content.get_view("navtree", self.context, self.request)
navtree_tile.update()
tree = [self.fix_node(node) for node in navtree_tile.tree]
return {
"@id": self.request.getURL(),
"items": tree,
}
Loading