Skip to content

Commit 4a16b69

Browse files
committed
Merge pull request django-cms#4175 from yakky/feature/merge_4107
Merge django-cms#4107 and backport django-cms#3509
2 parents 8bdef8d + 58957a6 commit 4a16b69

File tree

4 files changed

+138
-3
lines changed

4 files changed

+138
-3
lines changed

cms/menu.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,7 +428,8 @@ class SoftRootCutter(Modifier):
428428

429429
def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb):
430430
# only apply this modifier if we're pre-cut (since what we do is cut)
431-
if post_cut:
431+
# or if no id argument is provided, indicating {% show_menu_below_id %}
432+
if post_cut or root_id:
432433
return nodes
433434
selected = None
434435
root_nodes = []

cms/tests/menu.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,107 @@ def test_not_in_navigation(self):
922922
child = children[0]
923923
self.assertEqual(child.id, c.publisher_public.id)
924924

925+
def test_menu_beyond_soft_root(self):
926+
"""
927+
Test for issue 4107
928+
929+
Build the following tree:
930+
931+
A
932+
|-B (soft_root)
933+
|-C
934+
"""
935+
stdkwargs = {
936+
'template': 'nav_playground.html',
937+
'language': 'en',
938+
'published': True,
939+
'in_navigation': True,
940+
}
941+
a = create_page('A', reverse_id='a', **stdkwargs)
942+
b = create_page('B', parent=a, soft_root=True, **stdkwargs)
943+
c = create_page('C', parent=b, **stdkwargs)
944+
945+
context = self.get_context(a.get_absolute_url())
946+
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
947+
tpl.render(context)
948+
nodes = context['children']
949+
# check whole menu
950+
self.assertEqual(len(nodes), 1)
951+
a_node = nodes[0]
952+
self.assertEqual(a_node.id, a.publisher_public.pk) # On A, show from A
953+
self.assertEqual(len(a_node.children), 1)
954+
b_node = a_node.children[0]
955+
self.assertEqual(b_node.id, b.publisher_public.pk)
956+
self.assertEqual(len(b_node.children), 1)
957+
c_node = b_node.children[0]
958+
self.assertEqual(c_node.id, c.publisher_public.pk)
959+
self.assertEqual(len(c_node.children), 0)
960+
961+
context = self.get_context(b.get_absolute_url())
962+
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
963+
tpl.render(context)
964+
nodes = context['children']
965+
# check whole menu
966+
self.assertEqual(len(nodes), 1)
967+
b_node = nodes[0]
968+
self.assertEqual(b_node.id, b.publisher_public.pk) # On B, show from B
969+
self.assertEqual(len(b_node.children), 1)
970+
c_node = b_node.children[0]
971+
self.assertEqual(c_node.id, c.publisher_public.pk)
972+
self.assertEqual(len(c_node.children), 0)
973+
974+
context = self.get_context(c.get_absolute_url())
975+
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
976+
tpl.render(context)
977+
nodes = context['children']
978+
# check whole menu
979+
self.assertEqual(len(nodes), 1)
980+
b_node = nodes[0]
981+
self.assertEqual(b_node.id, b.publisher_public.pk) # On C, show from B
982+
self.assertEqual(len(b_node.children), 1)
983+
c_node = b_node.children[0]
984+
self.assertEqual(c_node.id, c.publisher_public.pk)
985+
self.assertEqual(len(c_node.children), 0)
986+
987+
context = self.get_context(a.get_absolute_url())
988+
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'a' 0 100 100 100 %}")
989+
tpl.render(context)
990+
nodes = context['children']
991+
# check whole menu
992+
self.assertEqual(len(nodes), 1)
993+
b_node = nodes[0]
994+
self.assertEqual(b_node.id, b.publisher_public.pk) # On A, show from B (since below A)
995+
self.assertEqual(len(b_node.children), 1)
996+
c_node = b_node.children[0]
997+
self.assertEqual(c_node.id, c.publisher_public.pk)
998+
self.assertEqual(len(c_node.children), 0)
999+
1000+
context = self.get_context(b.get_absolute_url())
1001+
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'a' 0 100 100 100 %}")
1002+
tpl.render(context)
1003+
nodes = context['children']
1004+
# check whole menu
1005+
self.assertEqual(len(nodes), 1)
1006+
b_node = nodes[0]
1007+
self.assertEqual(b_node.id, b.publisher_public.pk) # On B, show from B (since below A)
1008+
self.assertEqual(len(b_node.children), 1)
1009+
c_node = b_node.children[0]
1010+
self.assertEqual(c_node.id, c.publisher_public.pk)
1011+
self.assertEqual(len(c_node.children), 0)
1012+
1013+
context = self.get_context(c.get_absolute_url())
1014+
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'a' 0 100 100 100 %}")
1015+
tpl.render(context)
1016+
nodes = context['children']
1017+
# check whole menu
1018+
self.assertEqual(len(nodes), 1)
1019+
b_node = nodes[0]
1020+
self.assertEqual(b_node.id, b.publisher_public.pk) # On C, show from B (since below A)
1021+
self.assertEqual(len(b_node.children), 1)
1022+
c_node = b_node.children[0]
1023+
self.assertEqual(c_node.id, c.publisher_public.pk)
1024+
self.assertEqual(len(c_node.children), 0)
1025+
9251026
def test_not_in_navigation_num_queries(self):
9261027
"""
9271028
Test for issue 521
@@ -959,6 +1060,36 @@ def test_not_in_navigation_num_queries(self):
9591060
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'a' 0 100 100 100 %}")
9601061
tpl.render(context)
9611062

1063+
def test_menu_in_soft_root(self):
1064+
"""
1065+
Test for issue 3504
1066+
1067+
Build the following tree:
1068+
1069+
A
1070+
|-B
1071+
C (soft_root)
1072+
"""
1073+
a = create_page('A', 'nav_playground.html', 'en', published=True,
1074+
in_navigation=True, reverse_id='a')
1075+
b = create_page('B', 'nav_playground.html', 'en', parent=a,
1076+
published=True, in_navigation=True)
1077+
c = create_page('C', 'nav_playground.html', 'en', published=True,
1078+
in_navigation=True, soft_root=True)
1079+
context = self.get_context(a.get_absolute_url())
1080+
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'a' %}")
1081+
tpl.render(context)
1082+
nodes = context['children']
1083+
self.assertEqual(len(nodes), 1)
1084+
node = nodes[0]
1085+
self.assertEqual(node.id, b.publisher_public.id)
1086+
context = self.get_context(c.get_absolute_url())
1087+
tpl = Template("{% load menu_tags %}{% show_menu_below_id 'a' %}")
1088+
tpl.render(context)
1089+
nodes = context['children']
1090+
self.assertEqual(len(nodes), 1)
1091+
node = nodes[0]
1092+
self.assertEqual(node.id, b.publisher_public.id)
9621093

9631094
class ViewPermissionMenuTests(SettingsOverrideTestCase):
9641095
settings_overrides = {

docs/reference/navigation.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,9 @@ You can give it the same optional parameters as ``show_menu``::
9898
{% show_menu_below_id "meta" 0 100 100 100 "myapp/menu.html" %}
9999
</ul>
100100

101-
Note that soft roots will not affect the menu when
102-
using ``show_menu_below_id``.
101+
Unlike :ttag:`show_menu`, however, soft roots will not affect the menu when
102+
using :ttag:`show_menu_below_id`.
103+
103104

104105
.. templatetag:: show_sub_menu
105106

menus/menu_pool.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ def _build_nodes(self, request, site_id):
209209
for menu_class_name in self.menus:
210210
menu = self.menus[menu_class_name]
211211
try:
212+
if isinstance(menu, type):
213+
menu = menu()
212214
nodes = menu.get_nodes(request)
213215
except NoReverseMatch:
214216
# Apps might raise NoReverseMatch if an apphook does not yet

0 commit comments

Comments
 (0)