Skip to content

Commit dac5885

Browse files
committed
Hide language when it only has one language for users without edit permission
1 parent 2b833b4 commit dac5885

File tree

2 files changed

+119
-91
lines changed

2 files changed

+119
-91
lines changed

djangocms_versioning/cms_toolbars.py

Lines changed: 80 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -345,79 +345,80 @@ def change_language_menu(self):
345345
)
346346
)
347347

348-
language_menu = self.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER)
349-
if not language_menu:
350-
return None
351-
352-
languages = get_language_dict(self.current_site.pk)
353-
remove = [(code, languages.get(code, code)) for code in self.page.get_languages() if code in languages]
354-
add = [code for code in languages.items() if code not in remove]
355-
copy = [
356-
(code, name) for code, name in languages.items() if code != self.current_lang and (code, name) in remove
357-
]
358-
359-
# ADD TRANSLATION — only if user has change permission
360-
if can_change and add:
361-
language_menu.add_break(ADD_PAGE_LANGUAGE_BREAK)
362-
363-
add_plugins_menu = language_menu.get_or_create_menu(f"{LANGUAGE_MENU_IDENTIFIER}-add", _("Add Translation"))
364-
365-
page_add_url = admin_reverse("cms_pagecontent_add")
366-
367-
for code, name in add:
368-
url = add_url_parameters(page_add_url, cms_page=self.page.pk, language=code)
369-
add_plugins_menu.add_modal_item(name, url=url)
370-
371-
# DELETE TRANSLATION — only if user has change permission
372-
if can_change and remove and ALLOW_DELETING_VERSIONS and CMS_SUPPORTS_DELETING_TRANSLATIONS: # fabian why?
373-
remove_plugins_menu = language_menu.get_or_create_menu(
374-
f"{LANGUAGE_MENU_IDENTIFIER}-del", _("Delete Translation")
375-
)
376-
disabled = len(remove) == 1
377-
for code, name in remove:
378-
pagecontent = self.page.get_admin_content(language=code)
379-
if pagecontent:
380-
translation_delete_url = admin_reverse("cms_pagecontent_delete", args=(pagecontent.pk,))
381-
url = add_url_parameters(translation_delete_url, language=code)
382-
on_close = REFRESH_PAGE
383-
if self.toolbar.get_object() == pagecontent and not disabled:
384-
other_content = next(
385-
(
386-
self.page.get_admin_content(lang)
387-
for lang in self.page.get_languages()
388-
if lang != pagecontent.language and lang in languages
389-
),
390-
None,
348+
if can_change:
349+
language_menu = self.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER)
350+
if not language_menu:
351+
return None
352+
353+
languages = get_language_dict(self.current_site.pk)
354+
remove = [(code, languages.get(code, code)) for code in self.page.get_languages() if code in languages]
355+
add = [code for code in languages.items() if code not in remove]
356+
copy = [
357+
(code, name) for code, name in languages.items() if code != self.current_lang and (code, name) in remove
358+
]
359+
360+
# ADD TRANSLATION — only if user has change permission
361+
if add:
362+
language_menu.add_break(ADD_PAGE_LANGUAGE_BREAK)
363+
364+
add_plugins_menu = language_menu.get_or_create_menu(f"{LANGUAGE_MENU_IDENTIFIER}-add", _("Add Translation"))
365+
366+
page_add_url = admin_reverse("cms_pagecontent_add")
367+
368+
for code, name in add:
369+
url = add_url_parameters(page_add_url, cms_page=self.page.pk, language=code)
370+
add_plugins_menu.add_modal_item(name, url=url)
371+
372+
# DELETE TRANSLATION — only if user has change permission
373+
if remove and ALLOW_DELETING_VERSIONS and CMS_SUPPORTS_DELETING_TRANSLATIONS: # fabian why?
374+
remove_plugins_menu = language_menu.get_or_create_menu(
375+
f"{LANGUAGE_MENU_IDENTIFIER}-del", _("Delete Translation")
376+
)
377+
disabled = len(remove) == 1
378+
for code, name in remove:
379+
pagecontent = self.page.get_admin_content(language=code)
380+
if pagecontent:
381+
translation_delete_url = admin_reverse("cms_pagecontent_delete", args=(pagecontent.pk,))
382+
url = add_url_parameters(translation_delete_url, language=code)
383+
on_close = REFRESH_PAGE
384+
if self.toolbar.get_object() == pagecontent and not disabled:
385+
other_content = next(
386+
(
387+
self.page.get_admin_content(lang)
388+
for lang in self.page.get_languages()
389+
if lang != pagecontent.language and lang in languages
390+
),
391+
None,
392+
)
393+
on_close = get_object_preview_url(other_content)
394+
remove_plugins_menu.add_modal_item(name, url=url, disabled=disabled, on_close=on_close)
395+
# COPY ALL PLUGINS — only if user can change AND in edit mode
396+
if self.toolbar.edit_mode_active and copy:
397+
copy_plugins_menu = language_menu.get_or_create_menu(
398+
f"{LANGUAGE_MENU_IDENTIFIER}-copy", _("Copy all plugins")
399+
)
400+
title = _("from %s")
401+
question = _("Are you sure you want to copy all plugins from %s?")
402+
item_added = False
403+
for code, name in copy:
404+
# Get the Draft or Published PageContent.
405+
page_content = self.page.get_admin_content(language=code)
406+
if page_content: # Only offer to copy if content for source language exists
407+
page_copy_url = admin_reverse("cms_pagecontent_copy_language", args=(page_content.pk,))
408+
copy_plugins_menu.add_ajax_item(
409+
title % name,
410+
action=page_copy_url,
411+
data={"source_language": code, "target_language": self.current_lang},
412+
question=question % name,
413+
on_success=self.toolbar.REFRESH_PAGE,
414+
)
415+
item_added = True
416+
if not item_added: # pragma: no cover
417+
copy_plugins_menu.add_link_item(
418+
_("No other language available"),
419+
url="#",
420+
disabled=True,
391421
)
392-
on_close = get_object_preview_url(other_content)
393-
remove_plugins_menu.add_modal_item(name, url=url, disabled=disabled, on_close=on_close)
394-
# COPY ALL PLUGINS — only if user can change AND in edit mode
395-
if can_change and self.toolbar.edit_mode_active and copy:
396-
copy_plugins_menu = language_menu.get_or_create_menu(
397-
f"{LANGUAGE_MENU_IDENTIFIER}-copy", _("Copy all plugins")
398-
)
399-
title = _("from %s")
400-
question = _("Are you sure you want to copy all plugins from %s?")
401-
item_added = False
402-
for code, name in copy:
403-
# Get the Draft or Published PageContent.
404-
page_content = self.page.get_admin_content(language=code)
405-
if page_content: # Only offer to copy if content for source language exists
406-
page_copy_url = admin_reverse("cms_pagecontent_copy_language", args=(page_content.pk,))
407-
copy_plugins_menu.add_ajax_item(
408-
title % name,
409-
action=page_copy_url,
410-
data={"source_language": code, "target_language": self.current_lang},
411-
question=question % name,
412-
on_success=self.toolbar.REFRESH_PAGE,
413-
)
414-
item_added = True
415-
if not item_added: # pragma: no cover
416-
copy_plugins_menu.add_link_item(
417-
_("No other language available"),
418-
url="#",
419-
disabled=True,
420-
)
421422

422423

423424
class VersioningBasicToolbar(BasicToolbar):
@@ -436,6 +437,13 @@ def add_language_menu(self):
436437
if len(languages) < 2:
437438
return # No need to show the language menu if there is only one language
438439

440+
page_languages = self.request.current_page.get_languages(admin_manager=True)
441+
change_permission = page_permissions.user_can_change_page(
442+
user=self.request.user, page=self.page, site=self.current_site
443+
)
444+
if len(page_languages) < 2 and not change_permission:
445+
return # No need to show language menu if current page has one language
446+
439447
language_menu = self.toolbar.get_or_create_menu(LANGUAGE_MENU_IDENTIFIER, _("Languages"), position=-1)
440448
for code, name in languages:
441449
# Get the page content, it could be draft too!

tests/test_toolbars.py

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -529,32 +529,52 @@ def test_change_language_menu_page_toolbar(self):
529529
lang_code = "fr" if "Française" in item.name else "it"
530530
self.assertIn(f"language={lang_code}", item.url)
531531

532-
@patch("cms_toolbars.ALLOW_DELETING_VERSIONS", True)
533-
@patch("cms_toolbars.CMS_SUPPORTS_DELETING_TRANSLATIONS", True)
534532
def test_language_menu_in_non_edit_mode(self):
535-
version = PageVersionFactory(content__language="en")
536-
PageContentWithVersionFactory(page=version.content.page, language="de")
537-
PageContentWithVersionFactory(page=version.content.page, language="it")
538-
page = version.content.page
539-
page.update_languages(["en", "de", "it"])
540-
533+
with patch.object(cms_toolbars, "ALLOW_DELETING_VERSIONS", True):
534+
with patch.object(cms_toolbars, "CMS_SUPPORTS_DELETING_TRANSLATIONS", True):
535+
version = PageVersionFactory(content__language="en")
536+
PageContentWithVersionFactory(page=version.content.page, language="de")
537+
PageContentWithVersionFactory(page=version.content.page, language="it")
538+
page = version.content.page
539+
page.update_languages(["en", "de", "it"])
540+
541+
request = self.get_page_request(
542+
page=page,
543+
path=get_object_preview_url(version.content),
544+
user=self.get_superuser(),
545+
)
546+
request.toolbar.set_object(version.content)
547+
request.toolbar.populate()
548+
request.toolbar.post_template_populate()
549+
550+
language_menu = request.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER)
551+
# 3 out of 4 populated languages, Break, Add Translation menu, Delete Translation
552+
self.assertEqual(language_menu.get_item_count(), 6)
553+
554+
language_menu_dict = {menu.name: list(menu.items) for key, menu in language_menu.menus.items()}
555+
self.assertIn("Add Translation", language_menu_dict.keys())
556+
self.assertNotIn("Copy all plugins", language_menu_dict.keys())
557+
self.assertIn("Delete Translation", language_menu_dict.keys())
558+
559+
def test_change_language_menu_page_toolbar_no_page_translations(self):
560+
"""
561+
Test that when we have a page with no translations, and the user does not
562+
have edit permission, then we shouln't display the language meny
563+
the language menu (because it will show with only one option)
564+
(Regression for: https://github.com/django-cms/djangocms-versioning/issues/469)
565+
"""
566+
page_content = PageContentWithVersionFactory()
541567
request = self.get_page_request(
542-
page=page,
543-
path=get_object_preview_url(version.content),
544-
user=self.get_superuser(),
568+
page=page_content.page,
569+
path=get_object_edit_url(page_content),
570+
user=self.get_staff_user_with_no_permissions(),
545571
)
546-
request.toolbar.set_object(version.content)
572+
request.toolbar.set_object(page_content)
547573
request.toolbar.populate()
548574
request.toolbar.post_template_populate()
549-
550575
language_menu = request.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER)
551-
# 3 out of 4 populated languages, Break, Add Translation menu, Delete Translation
552-
self.assertEqual(language_menu.get_item_count(), 6)
576+
self.assertIsNone(language_menu)
553577

554-
language_menu_dict = {menu.name: list(menu.items) for key, menu in language_menu.menus.items()}
555-
self.assertIn("Add Translation", language_menu_dict.keys())
556-
self.assertNotIn("Copy all plugins", language_menu_dict.keys())
557-
self.assertIn("Delete Translation", language_menu_dict.keys())
558578

559579
@skipIf(cms_version <= Version("4.1.4"), "For CMS 4.1.5 and bove: Add delete translation menu")
560580
def test_change_language_menu_page_toolbar_including_delete(self):

0 commit comments

Comments
 (0)