8000 Fixed #6192 -- Filter out pages in the menu based on supported user l… · django-cms/django-cms@53b218c · GitHub
[go: up one dir, main page]

Skip to content

Commit 53b218c

Browse files
authored
Fixed #6192 -- Filter out pages in the menu based on supported user languages (#6193)
1 parent 2011892 commit 53b218c

File tree

2 files changed

+125
-22
lines changed

2 files changed

+125
-22
lines changed

cms/cms_menus.py

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from cms.utils.compat import DJANGO_1_9
1111
from cms.utils.conf import get_cms_setting
1212
from cms.utils.i18n import (
13-
get_default_language_for_site,
1413
get_fallback_languages,
14+
get_public_languages,
1515
hide_untranslated,
1616
is_valid_site_language,
1717
)
@@ -215,27 +215,24 @@ def get_nodes(self, request):
215215
_hide_untranslated = False
216216

217217
if _valid_language:
218-
fallbacks = get_fallback_languages(lang, site_id=site.pk) or []
218+
# The request language has been explicitly configured
219+
# for the current site.
220+
if _hide_untranslated:
221+
fallbacks = []
222+
else:
223+
fallbacks = get_fallback_languages(lang, site_id=site.pk)
219224
languages = [lang] + [_lang for _lang in fallbacks if _lang != lang]
220225
else:
221226
# The request language is not configured for the current site.
222-
# Fallback to the default language configured for the current site.
223-
languages = [get_default_language_for_site(site.pk)]
227+
# Fallback to all configured public languages for the current site.
228+
languages = get_public_languages(site.pk)
224229
fallbacks = languages
225230

8000
226-
if _valid_language and (_hide_untranslated or not fallbacks):
227-
# The language is correctly configured for the site.
228-
# But the user has opted out of displaying untranslated pages
229-
# OR has not configured any fallbacks.
230-
if self.renderer.draft_mode_active:
231-
nodes = nodes.filter(page__title_set__language=lang)
232-
else:
233-
nodes = nodes.filter(page__publisher_public__title_set__language=lang)
234-
languages = [lang]
235-
236231
if self.renderer.draft_mode_active:
232+
nodes = nodes.filter(page__title_set__language__in=languages)
237233
nodes = nodes.select_related('page', 'parent__page')
238234
else:
235+
nodes = nodes.filter(page__publisher_public__title_set__language__in=languages)
239236
nodes = nodes.select_related(
240237
'page__publisher_public',
241238
'parent__page__publisher_public',

cms/tests/test_menu.py

Lines changed: 114 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -921,15 +921,108 @@ def test_render_menu_with_invalid_language(self):
921921
language on the current site.
922922
"""
923923
# Refs - https://github.com/divio/django-cms/issues/6179
924-
de_site = Site.objects.create(id=2, name='example-2.com', domain='example-2.com')
925-
defaults = {
926-
'site': de_site,
924+
site_2 = Site.objects.create(id=2, name='example-2.com', domain='example-2.com')
925+
de_defaults = {
926+
'site': site_2,
927927
'template': 'nav_playground.html',
928928
'language': 'de',
929929
}
930-
create_page('DE-P1', published=True, in_navigation=True, **defaults)
931-
create_page('DE-P2', published=True, in_navigation=True, **defaults)
932-
create_page('DE-P3', published=True, in_navigation=True, **defaults)
930+
fr_defaults = {
931+
'site': site_2,
932+
'template': 'nav_playground.html',
933+
'language': 'fr',
934+
}
935+
create_page('DE-P1', published=True, in_navigation=True, **de_defaults)
936+
create_page('DE-P2', published=True, in_navigation=True, **de_defaults)
937+
create_page('DE-P3', published=True, in_navigation=True, **de_defaults)
938+
create_page('FR-P1', published=True, in_navigation=True, **fr_defaults)
939+
create_page('FR-P2', published=True, in_navigation=True, **fr_defaults)
940+
941+
with self.settings(SITE_ID=2):
942+
request = self.get_request('/en/')
943+
context = Context()
944+
context['request'] = request
945+
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
946+
tpl.render(context)
947+
nodes = context['children']
948+
self.assertEqual(len(nodes), 5)
949+
self.assertEqual(nodes[0].title, 'DE-P1')
950+
self.assertEqual(nodes[0].get_absolute_url(), '/de/de-p1/')
951+
self.assertEqual(nodes[1].title, 'DE-P2')
952+
self.assertEqual(nodes[1].get_absolute_url(), '/de/de-p2/')
953+
self.assertEqual(nodes[2].title, 'DE-P3')
954+
self.assertEqual(nodes[2].get_absolute_url(), '/de/de-p3/')
955+
self.assertEqual(nodes[3].title, 'FR-P1')
956+
self.assertEqual(nodes[3].get_absolute_url(), '/fr/fr-p1/')
957+
self.assertEqual(nodes[4].title, 'FR-P2')
958+
self.assertEqual(nodes[4].get_absolute_url(), '/fr/fr-p2/')
959+
960+
menu_pool.clear(site_id=2)
961+
962+
with self.settings(SITE_ID=2):
963+
request = self.get_request('/en/de-p2/')
964+
context = Context()
965+
context['request'] = request
966+
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
967+
tpl.render(context)
968+
nodes = context['children']
969+
self.assertEqual(len(nodes), 5)
970+
self.assertEqual(nodes[0].title, 'DE-P1')
971+
self.assertEqual(nodes[0].get_absolute_url(), '/de/de-p1/')
972+
self.assertEqual(nodes[1].title, 'DE-P2')
973+
self.assertEqual(nodes[1].get_absolute_url(), '/de/de-p2/')
974+
self.assertEqual(nodes[2].title, 'DE-P3')
975+
self.assertEqual(nodes[2].get_absolute_url(), '/de/de-p3/')
976+
self.assertEqual(nodes[3].title, 'FR-P1')
977+
self.assertEqual(nodes[3].get_absolute_url(), '/fr/fr-p1/')
978+
self.assertEqual(nodes[4].title, 'FR-P2')
979+
self.assertEqual(nodes[4].get_absolute_url(), '/fr/fr-p2/')
980+
981+
def test_render_menu_with_invalid_language_and_page(self):
982+
"""
983+
This tests an edge-case where the user requests a
984+
language not configure for the current site
985+
while having pages on the current site with unconfigured
986+
translations.
987+
"""
988+
# Refs - https://github.com/divio/django-cms/issues/6179
989+
site_2 = Site.objects.create(id=2, name='example-2.com', domain='example-2.com')
990+
de_defaults = {
991+
'site': site_2,
992+
'template': 'nav_playground.html',
993+
'language': 'de',
994+
'in_navigation': True,
995+
}
996+
nl_defaults = {
997+
'site': site_2,
998+
'template': 'nav_playground.html',
999+
'in_navigation': True,
1000+
}
1001+
create_page('DE-P1', published=True, **de_defaults)
1002+
create_page('DE-P2', published=True, **de_defaults)
1003+
create_page('DE-P3', published=True, **de_defaults)
1004+
1005+
# The nl language is not configured for the current site
1006+
# as a result, we have to create the pages manually.
1007+
nl_page_1 = Page.objects.create(**nl_defaults)
1008+
nl_page_1.attach_site(site=site_2, target=None)
1009+
nl_page_1.title_set.create(
1010+
language='nl',
1011+
title='NL-P1',
1012+
slug='nl-p1',
1013+
)
1014+
nl_page_1.publish('nl')
1015+
1016+
nl_page_2 = Page.objects.create(**nl_defaults)
1017+
nl_page_2.attach_site(site=site_2, target=None)
1018+
nl_page_2.title_set.create(
1019+
language='nl',
1020+
title='NL-P2',
1021+
slug='nl-p2',
1022+
)
1023+
nl_page_2.publish('nl')
1024+
create_title('fr', 'FR-P2', nl_page_2)
1025+
nl_page_2.publish('fr')
9331026

9341027
with self.settings(SITE_ID=2):
9351028
request = self.get_request('/en/')
@@ -938,13 +1031,17 @@ def test_render_menu_with_invalid_language(self):
9381031
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
9391032
tpl.render(context)
9401033
nodes = context['children']
941-
self.assertEqual(len(nodes), 3)
1034+
self.assertEqual(len(nodes), 4)
9421035
self.assertEqual(nodes[0].title, 'DE-P1')
9431036
self.assertEqual(nodes[0].get_absolute_url(), '/de/de-p1/')
9441037
self.assertEqual(nodes[1].title, 'DE-P2')
9451038
self.assertEqual(nodes[1].get_absolute_url(), '/de/de-p2/')
9461039
self.assertEqual(nodes[2].title, 'DE-P3')
9471040
self.assertEqual(nodes[2].get_absolute_url(), '/de/de-p3/')
1041+
self.assertEqual(nodes[3].title, 'FR-P2')
1042+
self.assertEqual(nodes[3].get_absolute_url(), '/fr/fr-p2/')
1043+
1044+
menu_pool.clear(site_id=2)
9481045

9491046
with self.settings(SITE_ID=2):
9501047
request = self.get_request('/en/de-p2/')
@@ -953,15 +1050,22 @@ def test_render_menu_with_invalid_language(self):
9531050
tpl = Template("{% load menu_tags %}{% show_menu 0 100 100 100 %}")
9541051
tpl.render(context)
9551052
nodes = context['children']
956-
self.assertEqual(len(nodes), 3)
1053+
self.assertEqual(len(nodes), 4)
9571054
self.assertEqual(nodes[0].title, 'DE-P1')
9581055
self.assertEqual(nodes[0].get_absolute_url(), '/de/de-p1/')
9591056
self.assertEqual(nodes[1].title, 'DE-P2')
9601057
self.assertEqual(nodes[1].get_absolute_url(), '/de/de-p2/')
9611058
self.assertEqual(nodes[2].title, 'DE-P3')
9621059
self.assertEqual(nodes[2].get_absolute_url(), '/de/de-p3/')
1060+
self.assertEqual(nodes[3].title, 'FR-P2')
1061+
self.assertEqual(nodes[3].get_absolute_url(), '/fr/fr-p2/')
9631062

9641063
def test_render_menu_with_invalid_language_and_no_fallbacks(self):
1064+
"""
1065+
The requested language is valid but there's no page
1066+
with it and the user has disabled all fallbacks.
1067+
The cms should render only nodes for the requested language.
1068+
"""
9651069
defaults = {
9661070
'template': 'nav_playground.html',
9671071
'language': 'de',
@@ -983,6 +1087,8 @@ def test_render_menu_with_invalid_language_and_no_fallbacks(self):
9831087
nodes = context['children']
9841088
self.assertEqual(len(nodes), 0)
9851089

1090+
menu_pool.clear(site_id=1)
1091+
9861092
with self.settings(CMS_LANGUAGES=lang_settings):
9871093
request = self.get_request('/en/de-p2/')
9881094
context = Context()

0 commit comments

Comments
 (0)
0