From e64dcdf5e207a42511db74ff3efd7f6a17ce0b1d Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 19 Dec 2023 11:08:08 +0000 Subject: [PATCH 1/2] Add MENU_TRIM_NON_VISIBLE_CHILD_ITEMS --- docs/configuration.rst | 8 ++++++++ simple_menu/menu.py | 11 ++++++----- simple_menu/tests/test_menu.py | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 520ec65..93ab924 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -18,5 +18,13 @@ MENU_HIDE_EMPTY ``MENU_HIDE_EMPTY`` controls if menu items without an explicit ``check`` callback should be visible even if they have no children +MENU_TRIM_NON_VISIBLE_CHILD_ITEMS +------------------- +**Default: ``True``** + +``MENU_TRIM_NON_VISIBLE_CHILD_ITEMS`` controls if children of menu items should be +removed from the ``item.children`` list if they are not visible. Retaining them +can be useful for breadcrumbs, but can also lead to unexpected results if you do not +check the ``visible`` property of the children in templates. .. _Django settings file: https://docs.djangoproject.com/en/dev/topics/settings/ diff --git a/simple_menu/menu.py b/simple_menu/menu.py index eb55d63..370170a 100644 --- a/simple_menu/menu.py +++ b/simple_menu/menu.py @@ -224,11 +224,12 @@ def process(self, request): child.parent = self child.process(request) - self.children = [ - child - for child in children - if child.visible - ] + if getattr(settings, 'MENU_TRIM_NON_VISIBLE_CHILD_ITEMS', True): + self.children = [ + child + for child in children + if child.visible + ] self.children.sort(key=lambda child: child.weight) # if we have no children and MENU_HIDE_EMPTY then we are not visible and should return diff --git a/simple_menu/tests/test_menu.py b/simple_menu/tests/test_menu.py index 3b5d35b..0cf31fa 100644 --- a/simple_menu/tests/test_menu.py +++ b/simple_menu/tests/test_menu.py @@ -4,7 +4,7 @@ from django.conf import settings from django.template import Template, Context -from django.test import TestCase +from django.test import TestCase, override_settings from django.test.client import RequestFactory from simple_menu import Menu, MenuItem @@ -264,3 +264,34 @@ def test_kwargs(self): self.assertTrue(item.arbitrary) self.assertEqual(item.dictionary, {'a': 1}) self.assertRaises(AttributeError, lambda: item.nope) + + @override_settings(MENU_TRIM_NON_VISIBLE_CHILD_ITEMS=False) + def test_trim_non_visible_child_items__disabled(self): + """ + Ensure that non-visible child items are NOT trimmed from the menu + """ + # Generate the menu + child_item = MenuItem("child", "/child", visible=False) + item = MenuItem("test", "/test", children=[child_item]) + + # Process the item + item.process() + + # Check that non-visible child items are still in the menu + self.assertIn(child_item, item.children) + + def test_trim_non_visible_child_items__enabled(self): + """ + Ensure that non-visible child items are trimmed from the menu. + + This is the default behaviour + """ + # Generate the menu + child_item = MenuItem("child", "/child", visible=False) + item = MenuItem("test", "/test", children=[child_item]) + + # Process the item + item.process() + + # Check that non-visible child items removed still in the menu + self.assertNotIn(child_item, item.children) From 4502ae662ff1ea0bfd4baf57f4b57b095d30d953 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 19 Dec 2023 11:16:47 +0000 Subject: [PATCH 2/2] test fix --- simple_menu/tests/test_menu.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/simple_menu/tests/test_menu.py b/simple_menu/tests/test_menu.py index 0cf31fa..a35206f 100644 --- a/simple_menu/tests/test_menu.py +++ b/simple_menu/tests/test_menu.py @@ -275,7 +275,8 @@ def test_trim_non_visible_child_items__disabled(self): item = MenuItem("test", "/test", children=[child_item]) # Process the item - item.process() + request = RequestFactory().get('/test') + item.process(request) # Check that non-visible child items are still in the menu self.assertIn(child_item, item.children) @@ -291,7 +292,8 @@ def test_trim_non_visible_child_items__enabled(self): item = MenuItem("test", "/test", children=[child_item]) # Process the item - item.process() + request = RequestFactory().get('/test') + item.process(request) # Check that non-visible child items removed still in the menu self.assertNotIn(child_item, item.children)