Skip to content

Breadcrumb will not show all nodes if selected node is from CMSAttachMenu for an AppHook. #6540

Open
@vstoykov

Description

@vstoykov

Summary

Sometimes when you are not logged in breadcrumb will not show all nodes if selected node is from CMSAttachMenu for an AppHook.

Let's use the following URL structure:

/ (CMS Page)
|-- /my-app/ (CMS Page with attached AppHook with menus)
    |-- /my-app/slug/ (URL handled from AppHook. There is `NavigationNode` for it by custom `CMSAttachMenu`)

We are opening /my-app/slug/

Expected behaviour

We expect the breadcrumb to show:

/ -> /my-app/ -> /my-app/slug/

Actual behavior

When you are logged out it randomly only shows:

/ -> /my-app/

Environment

  • Python version: < 3.6
  • Django version: 1.11.*
  • django CMS version: 3.5.2

The issue does not occur on Python 3.6

Extra details

I'm not sure if #6514 is related or not.

From my observations the cause for my problem is that in the {% show_breadcrumb %} the currently selected node is got by the following code:

selected = next((node for node in nodes if node.selected), None)

which will find the first node with is marked as selected.

The problem is that in the nodes list if there are extensions there can be more than one selected node (at least from what I found). In my case both /my-app/ and /my-app/slug/ was marked as selected. Depending on the order of the nodes if the right one was found first then the breadcrumb will be shown correctly, if the wrong one was first then there will be missing elements in the breadcrumb.

This problem does not occur in Python 3.6 (CPython 3.6) because dicts are ordered (preserve insertion order). My custom menu is registered in the menu pool as soon as server starts. On the other hand CMSMenu is registered on first request. For that reason when building the list of nodes in Python 3.6 custom nodes always comes before nodes for CMS pages and everything works fine. In Python >= 3.3 < 3.6 dicts has random order on every interpreter start which makes this problem inconsistent (sometime works, sometimes not).

I was not tested with Python 2.7 (there order of dicts should be somewhat predictable)

The problem also does not occur when in edit mode because for some reason the node for the page is not marked as selected.

There are few possible solutions that came to my mind:

  1. No matter how many selected nodes there are in the list (I think maximum of two - the node for the CMS page with AppHook and the node for the actual view) to use the node with higher level.
  2. Ensure that there is only one selected node in the list.
  3. Use OrderedDict for Python versions < 3.6 in MenuPool.menus and local variable registered_menus in MenuPool.get_registered_menus which is returned as result and then assigned to MenuRenderer.menus

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions