Skip to content

Commit 3ec8f52

Browse files
authored
Merge branch 'master' into fix-multi-site
2 parents 1a4f320 + 08df487 commit 3ec8f52

File tree

23 files changed

+1765
-844
lines changed

23 files changed

+1765
-844
lines changed

.github/workflows/frontend.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- uses: actions/checkout@v5
2020

2121
- name: Set up Node.js
22-
uses: actions/setup-node@v4
22+
uses: actions/setup-node@v6
2323
with:
2424
node-version: '24'
2525
cache: 'npm'

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
- uses: actions/checkout@v5
1313

1414
- name: Install uv
15-
uses: astral-sh/setup-uv@v5
15+
uses: astral-sh/setup-uv@v7
1616

1717
- name: Install ruff
1818
run: uv tool install ruff

.github/workflows/test.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
with:
4949
python-version: ${{ matrix.python-version }}
5050
- name: Install uv
51-
uses: astral-sh/setup-uv@v5
51+
uses: astral-sh/setup-uv@v7
5252
- name: Install dependencies
5353
run: |
5454
sudo apt install gettext gcc -y
@@ -121,7 +121,7 @@ jobs:
121121
with:
122122
python-version: ${{ matrix.python-version }}
123123
- name: Install uv
124-
uses: astral-sh/setup-uv@v5
124+
uses: astral-sh/setup-uv@v7
125125
- name: Install dependencies
126126
run: |
127127
uv pip install --system -r tests/requirements/${{ matrix.requirements-file }}
@@ -188,7 +188,7 @@ jobs:
188188
with:
189189
python-version: ${{ matrix.python-version }}
190190
- name: Install uv
191-
uses: astral-sh/setup-uv@v5
191+
uses: astral-sh/setup-uv@v7
192192
- name: Install dependencies
193193
run: |
194194
uv pip install --system -r tests/requirements/${{ matrix.requirements-file }}
@@ -223,7 +223,7 @@ jobs:
223223
with:
224224
python-version: ${{ matrix.python-version }}
225225
- name: Install uv
226-
uses: astral-sh/setup-uv@v5
226+
uses: astral-sh/setup-uv@v7
227227
- name: Install dependencies
228228
run: |
229229
uv pip install --system -r tests/requirements/${{ matrix.requirements-file }}
@@ -258,7 +258,7 @@ jobs:
258258
with:
259259
python-version: ${{ matrix.python-version }}
260260
- name: Install uv
261-
uses: astral-sh/setup-uv@v5
261+
uses: astral-sh/setup-uv@v7
262262
- name: Install dependencies
263263
run: |
264264
uv pip install --system -r tests/requirements/${{ matrix.requirements-file }}

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Testing
5252

5353
To run all the tests the only thing you need to do is run::
5454

55-
pip install -r tests/requirements.txt
55+
pip install -r tests/requirements/requirements_dev.txt
5656
python test_settings.py
5757

5858

djangocms_versioning/cms_toolbars.py

Lines changed: 46 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,7 @@ def _is_versioned(self):
5757
versioning
5858
"""
5959
versioning_extension = apps.get_app_config("djangocms_versioning").cms_extension
60-
return versioning_extension.is_content_model_versioned(
61-
self.toolbar.obj.__class__
62-
)
60+
return versioning_extension.is_content_model_versioned(self.toolbar.obj.__class__)
6361

6462
def _get_proxy_model(self):
6563
"""Helper method to get the proxy model class for the content
@@ -68,8 +66,7 @@ def _get_proxy_model(self):
6866
return self._get_versionable().version_model_proxy
6967

7068
def _add_publish_button(self):
71-
"""Helper method to add a publish button to the toolbar
72-
"""
69+
"""Helper method to add a publish button to the toolbar"""
7370
# Check if object is registered with versioning otherwise don't add
7471
if not self._is_versioned():
7572
return
@@ -101,8 +98,7 @@ def add_edit_button(self):
10198
self._add_unlock_button()
10299

103100
def _add_edit_button(self, disabled=False):
104-
"""Helper method to add an edit button to the toolbar
105-
"""
101+
"""Helper method to add an edit button to the toolbar"""
106102
item = ButtonList(side=self.toolbar.RIGHT)
107103
proxy_model = self._get_proxy_model()
108104
version = Version.objects.get_for_content(self.toolbar.obj)
@@ -111,9 +107,9 @@ def _add_edit_button(self, disabled=False):
111107
f"admin:{proxy_model._meta.app_label}_{proxy_model.__name__.lower()}_edit_redirect",
112108
args=(version.pk,),
113109
)
114-
pks_for_grouper = version.versionable.for_content_grouping_values(
115-
version.content
116-
).values_list("pk", flat=True)
110+
pks_for_grouper = version.versionable.for_content_grouping_values(version.content).values_list(
111+
"pk", flat=True
112+
)
117113
content_type = ContentType.objects.get_for_model(version.content)
118114
draft_exists = Version.objects.filter(
119115
object_id__in=pks_for_grouper, content_type=content_type, state=DRAFT
@@ -127,8 +123,7 @@ def _add_edit_button(self, disabled=False):
127123
self.toolbar.add_item(item)
128124

129125
def _add_unlock_button(self):
130-
"""Helper method to add an edit button to the toolbar
131-
"""
126+
"""Helper method to add an edit button to the toolbar"""
132127
if LOCK_VERSIONS and self._is_versioned():
133128
item = ButtonList(side=self.toolbar.RIGHT)
134129
proxy_model = self._get_proxy_model()
@@ -166,8 +161,7 @@ def _add_lock_message(self):
166161
self.toolbar.add_item(lock_message, position=0)
167162

168163
def _add_revert_button(self, disabled=False):
169-
"""Helper method to add a revert button to the toolbar
170-
"""
164+
"""Helper method to add a revert button to the toolbar"""
171165
# Check if object is registered with versioning otherwise don't add
172166
if not self._is_versioned():
173167
return
@@ -188,8 +182,7 @@ def _add_revert_button(self, disabled=False):
188182
self.toolbar.add_item(item)
189183

190184
def _add_versioning_menu(self):
191-
""" Helper method to add version menu in the toolbar
192-
"""
185+
"""Helper method to add version menu in the toolbar"""
193186
# Check if object is registered with versioning otherwise don't add
194187
if not self._is_versioned():
195188
return
@@ -217,13 +210,15 @@ def _add_versioning_menu(self):
217210
proxy_model = self._get_proxy_model()
218211
url = reverse(
219212
f"admin:{proxy_model._meta.app_label}_{proxy_model.__name__.lower()}_compare",
220-
args=(version.source.pk,)
213+
args=(version.source.pk,),
221214
)
222215

223-
url += "?" + urlencode({
224-
"compare_to": version.pk,
225-
"back": self.toolbar.request_path,
226-
})
216+
url += "?" + urlencode(
217+
{
218+
"compare_to": version.pk,
219+
"back": self.toolbar.request_path,
220+
}
221+
)
227222
versioning_menu.add_link_item(name, url=url)
228223
# Discard changes menu entry (wrt to source)
229224
if version.check_discard.as_bool(self.request.user): # pragma: no cover
@@ -232,26 +227,22 @@ def _add_versioning_menu(self):
232227
_("Discard Changes"),
233228
url=reverse(
234229
f"admin:{proxy_model._meta.app_label}_{proxy_model.__name__.lower()}_discard",
235-
args=(version.pk,)
236-
)
230+
args=(version.pk,),
231+
),
237232
)
238233

239234
def _get_published_page_version(self):
240-
"""Returns a published page if one exists for the toolbar object
241-
"""
235+
"""Returns a published page if one exists for the toolbar object"""
242236
language = self.current_lang
243237

244238
# Exit the current toolbar object is not a Page / PageContent instance
245239
if not isinstance(self.toolbar.obj, PageContent) or not self.page:
246240
return
247241

248-
return PageContent.objects.filter(
249-
page=self.page, language=language
250-
).select_related("page").first()
242+
return PageContent.objects.filter(page=self.page, language=language).select_related("page").first()
251243

252244
def _add_view_published_button(self):
253-
"""Helper method to add a publish button to the toolbar
254-
"""
245+
"""Helper method to add a publish button to the toolbar"""
255246
# Check if object is registered with versioning otherwise don't add
256247
if not self._is_versioned():
257248
return
@@ -351,50 +342,38 @@ def override_language_menu(self):
351342
language_menu.add_link_item(name, url=url, active=self.current_lang == code)
352343

353344
def change_language_menu(self):
354-
if self.toolbar.edit_mode_active and self.page:
355-
can_change = page_permissions.user_can_change_page(
345+
can_change = (
346+
self.page
347+
and page_permissions.user_can_change_page(
356348
user=self.request.user, page=self.page, site=self.current_site
357349
)
358-
else:
359-
can_change = False
350+
)
360351

361352
if can_change:
362353
language_menu = self.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER)
363354
if not language_menu:
364355
return None
365356

366357
languages = get_language_dict(self.current_site.pk)
367-
remove = [
368-
(code, languages.get(code, code))
369-
for code in self.page.get_languages()
370-
if code in languages
371-
]
372-
add = [
373-
code
374-
for code in languages.items()
375-
if code not in remove
376-
]
358+
remove = [(code, languages.get(code, code)) for code in self.page.get_languages() if code in languages]
359+
add = [code for code in languages.items() if code not in remove]
377360
copy = [
378-
(code, name)
379-
for code, name in languages.items()
380-
if code != self.current_lang and (code, name) in remove
361+
(code, name) for code, name in languages.items() if code != self.current_lang and (code, name) in remove
381362
]
382363

364+
# ADD TRANSLATION — only if user has change permission
383365
if add:
384366
language_menu.add_break(ADD_PAGE_LANGUAGE_BREAK)
385367

386-
add_plugins_menu = language_menu.get_or_create_menu(
387-
f"{LANGUAGE_MENU_IDENTIFIER}-add", _("Add Translation")
388-
)
368+
add_plugins_menu = language_menu.get_or_create_menu(f"{LANGUAGE_MENU_IDENTIFIER}-add", _("Add Translation")) # noqa: E501
389369

390370
page_add_url = admin_reverse("cms_pagecontent_add")
391371

392372
for code, name in add:
393-
url = add_url_parameters(
394-
page_add_url, cms_page=self.page.pk, language=code
395-
)
373+
url = add_url_parameters(page_add_url, cms_page=self.page.pk, language=code)
396374
add_plugins_menu.add_modal_item(name, url=url)
397375

376+
# DELETE TRANSLATION — only if user has change permission
398377
if remove and ALLOW_DELETING_VERSIONS and CMS_SUPPORTS_DELETING_TRANSLATIONS:
399378
remove_plugins_menu = language_menu.get_or_create_menu(
400379
f"{LANGUAGE_MENU_IDENTIFIER}-del", _("Delete Translation")
@@ -408,12 +387,17 @@ def change_language_menu(self):
408387
on_close = REFRESH_PAGE
409388
if self.toolbar.get_object() == pagecontent and not disabled:
410389
other_content = next(
411-
(self.page.get_admin_content(lang) for lang in self.page.get_languages()
412-
if lang != pagecontent.language and lang in languages), None)
390+
(
391+
self.page.get_admin_content(lang)
392+
for lang in self.page.get_languages()
393+
if lang != pagecontent.language and lang in languages
394+
),
395+
None,
396+
)
413397
on_close = get_object_preview_url(other_content)
414398
remove_plugins_menu.add_modal_item(name, url=url, disabled=disabled, on_close=on_close)
415-
416-
if copy:
399+
# COPY ALL PLUGINS — only if user can change AND in edit mode
400+
if self.toolbar.edit_mode_active and copy:
417401
copy_plugins_menu = language_menu.get_or_create_menu(
418402
f"{LANGUAGE_MENU_IDENTIFIER}-copy", _("Copy all plugins")
419403
)
@@ -426,9 +410,11 @@ def change_language_menu(self):
426410
if page_content: # Only offer to copy if content for source language exists
427411
page_copy_url = admin_reverse("cms_pagecontent_copy_language", args=(page_content.pk,))
428412
copy_plugins_menu.add_ajax_item(
429-
title % name, action=page_copy_url,
413+
title % name,
414+
action=page_copy_url,
430415
data={"source_language": code, "target_language": self.current_lang},
431-
question=question % name, on_success=self.toolbar.REFRESH_PAGE
416+
question=question % name,
417+
on_success=self.toolbar.REFRESH_PAGE,
432418
)
433419
item_added = True
434420
if not item_added: # pragma: no cover
@@ -471,8 +457,7 @@ def replace_toolbar(old, new):
471457
new_name = ".".join((new.__module__, new.__name__))
472458
old_name = ".".join((old.__module__, old.__name__))
473459
toolbar_pool.toolbars = OrderedDict(
474-
(new_name, new) if name == old_name else (name, toolbar)
475-
for name, toolbar in toolbar_pool.toolbars.items()
460+
(new_name, new) if name == old_name else (name, toolbar) for name, toolbar in toolbar_pool.toolbars.items()
476461
)
477462

478463

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)