8000 fix: Page Content Extension toolbar (#7708) · django-cms/django-cms@5af7fc7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5af7fc7

Browse files
fsbraunjrief
andauthored
fix: Page Content Extension toolbar (#7708)
* Fix: page content extension toolbar naming and use latest_content filter * Align page content extension menu with shown page content * Deprecate the use for more than one page content object * fix linting issue * Accommodate review feedback * Add some comments * Readability improvement `ruff format` * One more readability improvement * Doc-string update * Fix typo Co-authored-by: Jacob Rief <jacob.rief@gmail.com>
1 parent 19c66fe commit 5af7fc7

File tree

2 files changed

+103
-48
lines changed

2 files changed

+103
-48
lines changed

cms/extensions/toolbar.py

Lines changed: 72 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
1+
import warnings
2+
13
from django.urls import NoReverseMatch
24

5+
from cms.models import PageContent
36
from cms.toolbar_base import CMSToolbar
47
from cms.utils import get_language_list
58
from cms.utils.page_permissions import user_can_change_page
69
from cms.utils.urlutils import admin_reverse
710

811

912
class ExtensionToolbar(CMSToolbar):
13+
"""Offers simplified API for providing the user access to the admin of page extensions and
14+
page content extensions through the toolbar."""
1015
model = None
1116
page = None
17+
page_content = None
1218

1319
def _setup_extension_toolbar(self):
1420
"""
@@ -22,12 +28,18 @@ def _setup_extension_toolbar(self):
2228
page = self._get_page()
2329

2430
if page and user_can_change_page(self.request.user, page=page):
25-
return self.toolbar.get_or_create_menu('page')
31+
return self.toolbar.get_or_create_menu("page")
2632
return
2733

2834
def _get_page(self):
2935
if not self.page:
30-
self.page = self.request.current_page
36+
obj = self.toolbar.get_object() # Try getting the PageContent object from the toolbar
37+
if isinstance(obj, PageContent):
38+
self.page = obj.page
39+
self.page_content = obj
40+
else:
41+
self.page = self.request.current_page # Otherwise get Page object from the request
42+
self.page_content = self.page.get_content_obj(self.current_lang)
3143
return self.page
3244

3345
def get_page_extension_admin(self):
@@ -45,60 +57,81 @@ def get_page_extension_admin(self):
4557
except self.model.DoesNotExist:
4658
page_extension = None
4759
try:
48-
model_name = self.model.__name__.lower()
60+
app_label, model_name = self.model._meta.app_label, self.model.__name__.lower()
4961
if page_extension:
50-
admin_url = admin_reverse(
51-
'%s_%s_change' % (self.model._meta.app_label, model_name),
52-
args=(page_extension.pk,))
62+
admin_url = admin_reverse(f"{app_label}_{model_name}_change", args=(page_extension.pk,))
5363
else:
54-
admin_url = "%s?extended_object=%s" % (
55-
admin_reverse('%s_%s_add' % (self.model._meta.app_label, model_name)),
56-
self.page.pk)
64+
admin_url = "{}?extended_object={}".format(
65+
admin_reverse(f"{app_label}_{model_name}_add"), self.page.pk
66+
)
5767
except NoReverseMatch: # pragma: no cover
5868
admin_url = None
5969
return page_extension, admin_url
6070

6171
def get_title_extension_admin(self, language=None):
6272
"""
63-
Get the admin urls for the title extensions menu items, depending on whether a TitleExtension instance exists
64-
for each PageContent in the current page.
65-
A single language can be passed to only work on a single title.
73+
Deprecated.
6674
67-
Return a list of tuples of the title extension and the url; the extension is None if no instance exists,
68-
the url is None is no admin is registered for the extension.
75+
Reflects now obsolete behavior in django CMS 3.x:
76+
77+
Get the admin urls for the page content extensions menu items, depending on whether a
78+
:class:`~cms.extensions.models.PageContentExtension` instance exists for each
79+
:class:`~cms.models.contentmodels.PageContent` in the current page.
80+
A single language can be passed to only work on a single page content object.
81+
82+
Return a list of tuples of the page content extension and the url; the extension is None
83+
if no instance exists, the url is None is no admin is registered for the extension.
6984
"""
85+
warnings.warn(
86+
"get_title_extension_admin has been deprecated and replaced by get_page_content_extension_admin",
87+
DeprecationWarning,
88+
stacklevel=2,
89+
)
7090
page = self._get_page()
91+
92+
page_contents = (
93+
page.pagecontent_set(manager="admin_manager")
94+
.latest_content()
95+
.filter(language__in=get_language_list(page.node.site_id))
96+
)
7197
urls = []
72-
if language:
73-
titles = page.get_content_obj(language),
74-
else:
75-
titles = page.pagecontent_set.filter(language__in=get_language_list(page.node.site_id))
76-
# Titles
77-
for title in titles:
78-
try:
79-
title_extension = self.model.objects.get(extended_object_id=title.pk)
80-
except self.model.DoesNotExist:
81-
title_extension = None
82-
try:
83-
model_name = self.model.__name__.lower()
84-
if title_extension:
85-
admin_url = admin_reverse(
86-
'%s_%s_change' % (self.model._meta.app_label, model_name),
87-
args=(title_extension.pk,))
88-
else:
89-
admin_url = "%s?extended_object=%s" % (
90-
admin_reverse('%s_%s_add' % (self.model._meta.app_label, model_name)),
91-
title.pk)
92-
except NoReverseMatch: # pragma: no cover
93-
admin_url = None
98+
99+
for page_content in page_contents:
100+
admin_url = self.get_page_content_extension_admin(page_content)
94101
if admin_url:
95-
urls.append((title_extension, admin_url))
102+
urls.append(admin_url)
96103
return urls
97104

105+
def get_page_content_extension_admin(self, page_content_obj=None):
106+
"""
107+
Get the admin url for the page content extensions menu item, depending on whether a
108+
:class:`~cms.extensions.models.PageContentExtension` instance exists for the
109+
:class:`~cms.models.contentmodels.PageContent` displayed.
110+
111+
Return a tuple of the page content extension and the url; the extension is None
112+
if no instance exists, the url is None is no admin is registered for the extension.
113+
"""
114+
self._get_page()
115+
page_content = page_content_obj or self.page_content
116+
try:
117+
pagecontent_extension = self.model.objects.get(extended_object_id=page_content.pk)
118+
except self.model.DoesNotExist:
119+
pagecontent_extension = None
120+
try:
121+
app_label, model_name = self.model._meta.app_label, self.model.__name__.lower()
122+
if pagecontent_extension:
123+
admin_url = admin_reverse(f"{app_label}_{model_name}_change", args=(pagecontent_extension.pk,))
124+
else:
125+
admin_url = "{}?extended_object={}".format(
126+
admin_reverse(f"{app_label}_{model_name}_add"), page_content.pk
127+
)
128+
except NoReverseMatch: # pragma: no cover
129+
admin_url = None
130+
return pagecontent_extension, admin_url
131+
98132
def _get_sub_menu(self, current_menu, key, label, position=None):
99133
"""
100134
Utility function to get a submenu of the current menu
101135
"""
102-
extension_menu = current_menu.get_or_create_menu(
103-
key, label, position=position)
136+
extension_menu = current_menu.get_or_create_menu(key, label, position=position)
104137
return extension_menu

cms/tests/test_extensions.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ def populate(self):
397397
self.assertIn("TestItem", response.rendered_content)
398398
toolbar_pool.toolbars = old_toolbars
399399

400-
def test_toolbar_title_extension(self):
400+
def test_toolbar_page_content_extension(self):
401401
old_toolbars = deepcopy(toolbar_pool.toolbars)
402402

403403
class SampleExtension(ExtensionToolbar):
@@ -407,20 +407,42 @@ def populate(self):
407407
current_page_menu = self._setup_extension_toolbar()
408408
if current_page_menu:
409409
position = 0
410-
urls = self.get_title_extension_admin()
411-
for title_extension, url in urls:
412-
current_page_menu.add_modal_item(
413-
'TestItem',
414-
url=url,
415-
disabled=not self.toolbar.edit_mode_active,
416-
position=position
417-
)
410+
pagecontent_extension, url = self.get_page_content_extension_admin()
411+
current_page_menu.add_modal_item(
412+
'TestItem',
413+
url=url,
414+
disabled=not self.toolbar.edit_mode_active,
415+
position=position
416+
)
418417
toolbar_pool.register(SampleExtension)
419418
with self.login_user_context(self.admin):
420419
response = self.client.get('{}?edit'.format(self.page.get_absolute_url()))
421420
self.assertIn("TestItem", response.rendered_content)
422421
toolbar_pool.toolbars = old_toolbars
423422

423+
def test_deprecated_title_extension(self):
424+
urls = []
425+
old_toolbars = deepcopy(toolbar_pool.toolbars)
426+
427+
class SampleExtensionToolbar2(ExtensionToolbar):
428+
model = MyPageContentExtension
429+
def populate(self):
430+
nonlocal urls
431+
urls = self.get_title_extension_admin()
432+
433+
toolbar_pool.register(SampleExtensionToolbar2)
434+
435+
message = "get_title_extension_admin has been deprecated and replaced by get_page_content_extension_admin"
436+
with self.login_user_context(self.admin):
437+
self.assertWarns(
438+
DeprecationWarning,
439+
message,
440+
lambda: self.client.get(self.page.get_absolute_url()),
441+
)
442+
443+
self.assertEqual(len(urls), 2)
444+
toolbar_pool.toolbars = old_toolbars
445+
424446
def test_admin_title_extension(self):
425447
with self.login_user_context(self.admin):
426448
# add a new extension

0 commit comments

Comments
 (0)
0