Skip to content

Commit

Permalink
Merge branch 'develop-4' into dependabot/npm_and_yarn/follow-redirect…
Browse files Browse the repository at this point in the history
…s-1.15.6
  • Loading branch information
fsbraun committed Apr 4, 2024
2 parents df271ec + 3a001a2 commit c96d96f
Show file tree
Hide file tree
Showing 27 changed files with 226 additions and 131 deletions.
5 changes: 5 additions & 0 deletions cms/admin/forms.py
Expand Up @@ -252,6 +252,11 @@ class AddPageForm(BasePageContentForm):
required=False,
widget=forms.HiddenInput(),
)
edit = forms.IntegerField(
# Got to edit/preview mode after adding
required=False,
widget=forms.HiddenInput(),
)
content_defaults = {
"in_navigation": True,
}
Expand Down
16 changes: 16 additions & 0 deletions cms/admin/pageadmin.py
Expand Up @@ -50,6 +50,7 @@
)
from cms.admin.permissionadmin import PERMISSION_ADMIN_INLINES
from cms.cache.permissions import clear_permission_cache
from cms.constants import MODAL_HTML_REDIRECT
from cms.models import (
CMSPlugin,
EmptyPageContent,
Expand All @@ -65,6 +66,7 @@
)
from cms.plugin_pool import plugin_pool
from cms.signals.apphook import set_restart_trigger
from cms.toolbar.utils import get_object_edit_url
from cms.utils import get_current_site, page_permissions, permissions
from cms.utils.admin import jsonify_request
from cms.utils.conf import get_cms_setting
Expand Down Expand Up @@ -980,6 +982,20 @@ def change_view(self, request, object_id, form_url='', extra_context=None):

return super().change_view(request, object_id, form_url=form_url, extra_context=context)

def response_add(self, request, obj):
redirect = request.POST.get("edit", False)
if redirect == "1":
from django.core.cache import cache

from cms.cache.permissions import get_cache_key, get_cache_permission_version
cache.delete(get_cache_key(request.user, 'change_page'), version=get_cache_permission_version())

# redirect to the edit view if added from the toolbar
url = get_object_edit_url(obj) # Redirects to preview if necessary
return HttpResponse(MODAL_HTML_REDIRECT.format(url=url))
return super().response_add(request, obj)


def get_filled_languages(self, request, page):
site_id = get_site(request).pk
filled_languages = page.get_languages()
Expand Down
9 changes: 1 addition & 8 deletions cms/cache/placeholder.py
Expand Up @@ -96,14 +96,7 @@ def _get_placeholder_cache_key(placeholder, lang, site_id, request, soft=False):
"""
prefix = get_cms_setting('CACHE_PREFIX')
version, vary_on_list = _get_placeholder_cache_version(placeholder, lang, site_id)
main_key = '{prefix}|render_placeholder|id:{id}|lang:{lang}|site:{site}|tz:{tz}|v:{version}'.format(
prefix=prefix,
id=placeholder.pk,
lang=lang,
site=site_id,
tz=get_timezone_name(),
version=version,
)
main_key = f'{prefix}|render_placeholder|id:{placeholder.pk}|lang:{lang}|site:{site_id}|tz:{get_timezone_name()}|v:{version}'

if not soft:
# We are about to write to the cache, so we want to get the latest
Expand Down
9 changes: 6 additions & 3 deletions cms/cms_toolbars.py
Expand Up @@ -429,8 +429,9 @@ def get_on_delete_redirect_url(self):

# if the current page has a parent in the request's current language redirect to it
if parent_page and language in parent_page.get_languages():
with force_language(language):
return parent_page.get_absolute_url(language=language)
return get_object_preview_url(
parent_page.pagecontent_set(manager="admin_manager").latest_content(language=language).first()
)

# else redirect to root, do not redirect to Page.objects.get_home() because user could have deleted the last
# page, if DEBUG == False this could cause a 404
Expand Down Expand Up @@ -498,7 +499,9 @@ def change_language_menu(self):
page_add_url = admin_reverse('cms_pagecontent_add')

for code, name in add:
url = add_url_parameters(page_add_url, cms_page=self.page.pk, language=code)
url = add_url_parameters(
page_add_url, cms_page=self.page.pk, parent_node=self.page.node.id, language=code
)
add_plugins_menu.add_modal_item(name, url=url)

if remove:
Expand Down
2 changes: 2 additions & 0 deletions cms/constants.py
Expand Up @@ -78,3 +78,5 @@
SCRIPT_USERNAME = 'script'

CMS_CONFIG_NAME = 'cms_config'

MODAL_HTML_REDIRECT = '<body><a class="cms-view-new-object" target="_top" href="{url}">Redirecting...</a></body>'
2 changes: 1 addition & 1 deletion cms/models/pagemodel.py
Expand Up @@ -607,7 +607,7 @@ def delete_translations(self, language=None):
else:
languages = [language]

self.pagecontent_set.filter(language__in=languages).delete()
self.pagecontent_set(manager="admin_manager").filter(language__in=languages).delete()

def save(self, **kwargs):
if self.reverse_id == "":
Expand Down
8 changes: 1 addition & 7 deletions cms/models/placeholdermodel.py
Expand Up @@ -53,13 +53,7 @@ def __str__(self):
return self.slot

def __repr__(self):
display = "<{module}.{class_name} id={id} slot='{slot}' object at {location}>".format(
module=self.__module__,
class_name=self.__class__.__name__,
id=self.pk,
slot=self.slot,
location=hex(id(self)),
)
display = f"<{self.__module__}.{self.__class__.__name__} id={self.pk} slot='{self.slot}' object at {hex(id(self))}>"
return display

def clear(self, language=None):
Expand Down
10 changes: 2 additions & 8 deletions cms/models/pluginmodel.py
Expand Up @@ -186,13 +186,7 @@ def __str__(self):
return force_str(self.pk)

def __repr__(self):
display = "<{module}.{class_name} id={id} plugin_type='{plugin_type}' object at {location}>".format(
module=self.__module__,
class_name=self.__class__.__name__,
id=self.pk,
plugin_type=(self.plugin_type),
location=hex(id(self)),
)
display = f"<{self.__module__}.{self.__class__.__name__} id={self.pk} plugin_type='{self.plugin_type}' object at {hex(id(self))}>"
return display

def get_plugin_name(self):
Expand All @@ -219,7 +213,7 @@ def get_plugin_class_instance(self, admin=None):
def get_plugin_instance(self, admin=None):
"""
For a plugin instance (usually as a CMSPluginBase), this method
returns the downcasted (i.e., correctly typed subclass of CMSPluginBase) instacnce and the plugin class
returns the downcasted (i.e., correctly typed subclass of CMSPluginBase) instance and the plugin class
:return: Tuple (instance, plugin)
Expand Down
8 changes: 8 additions & 0 deletions cms/static/cms/js/modules/cms.modal.js
Expand Up @@ -910,6 +910,14 @@ class Modal {
return;
}

// check if we are redirected - should only happen after successful form submission
var redirect = body.find('a.cms-view-new-object').attr('href');

if (redirect) {
Helpers.reloadBrowser(redirect, false);
return true;
}

// tabindex is required for keyboard navigation
// body.attr('tabindex', '0');
iframe.on('focus', function() {
Expand Down
10 changes: 7 additions & 3 deletions cms/templatetags/cms_js_tags.py
Expand Up @@ -30,17 +30,21 @@ def bool(value):
return 'false'


@register.simple_tag()
def render_cms_structure_js(renderer, obj):
@register.simple_tag(takes_context=True)
def render_cms_structure_js(context, renderer, obj):
markup_bits = []
obj_placeholders_by_slot = rescan_placeholders_for_obj(obj)
declared_placeholders = get_declared_placeholders_for_obj(obj)
try:
lang = context["request"].toolbar.request_language
except AttributeError:
lang = None

for placeholder_node in declared_placeholders:
obj_placeholder = obj_placeholders_by_slot.get(placeholder_node.slot)

if obj_placeholder:
placeholder_js = renderer.render_placeholder(obj_placeholder, language=None, page=obj)
placeholder_js = renderer.render_placeholder(obj_placeholder, language=lang, page=obj)
markup_bits.append(placeholder_js)

return mark_safe('\n'.join(markup_bits))
Expand Down
12 changes: 12 additions & 0 deletions cms/test_utils/testcases.py
Expand Up @@ -153,6 +153,18 @@ def add_page_permission(self, user, page, **kwargs):
return pp

def get_page_title_obj(self, page, language="en"):
import warnings

from cms.utils.compat.warnings import RemovedInDjangoCMS42Warning

warnings.warn(
"get_page_title_obj is deprecated, use get_pagecontent_obj instead",
RemovedInDjangoCMS42Warning,
stacklevel=2,
)
return PageContent.objects.get(page=page, language=language)

def get_pagecontent_obj(self, page, language="en"):
return PageContent.objects.get(page=page, language=language)

def _create_user(self, username, is_staff=False, is_superuser=False,
Expand Down
2 changes: 1 addition & 1 deletion cms/tests/test_admin.py
Expand Up @@ -371,7 +371,7 @@ def get_page(self):

def test_change_innavigation(self):
page = self.get_page()
content = self.get_page_title_obj(page, 'en')
content = self.get_pagecontent_obj(page, 'en')
permless = self.get_permless()
admin_user = self.get_admin()
pagecontent_admin = self.pagecontent_admin_class
Expand Down
2 changes: 1 addition & 1 deletion cms/tests/test_cache.py
Expand Up @@ -457,7 +457,7 @@ def test_no_page_cache_on_toolbar_edit(self):
superuser = self.get_superuser()
# Create a test page
page = create_page("test page 1", "nav_playground.html", "en")
page_content = self.get_page_title_obj(page)
page_content = self.get_pagecontent_obj(page)
page_url = page.get_absolute_url()
page_edit_url = get_object_edit_url(page_content)

Expand Down
2 changes: 1 addition & 1 deletion cms/tests/test_extensions.py
Expand Up @@ -289,7 +289,7 @@ def setUp(self):

def test_duplicate_extensions(self):
with self.login_user_context(self.admin):
content = self.get_page_title_obj(self.page, 'en')
content = self.get_pagecontent_obj(self.page, 'en')
# create page copy
page_data = {
'title': 'type1', 'slug': 'type1', '_save': 1, 'template': 'nav_playground.html',
Expand Down
52 changes: 49 additions & 3 deletions cms/tests/test_page_admin.py
Expand Up @@ -32,6 +32,7 @@
LanguageOverride,
UserLoginContext,
)
from cms.toolbar.utils import get_object_edit_url
from cms.utils.compat import DJANGO_4_2
from cms.utils.compat.dj import installed_apps
from cms.utils.conf import get_cms_setting
Expand Down Expand Up @@ -1310,7 +1311,7 @@ def test_form_url_page_change(self):
with self.login_user_context(superuser):
content_admin = PageContentAdmin(PageContent, admin.site)
page = self.get_page()
content = self.get_page_title_obj(page, 'en')
content = self.get_pagecontent_obj(page, 'en')
form_url = self.get_page_change_uri('en', page)
# Middleware is needed to correctly setup the environment for the admin
request = self.get_request()
Expand Down Expand Up @@ -1558,6 +1559,51 @@ def test_page_tree_render_localized_page_ids(self):
self.assertEqual(response.status_code, 200)


class PageActionsTestCase(PageTestBase):
def setUp(self):
self.admin = self.get_superuser()
self.site = Site.objects.get(pk=1)
self.page = create_page(
'My Page', 'nav_playground.html', 'en',
slug="ok",
site=self.site, created_by=self.admin)

def test_add_page_redirect(self):
"""When adding the edit parameter to the add page form, the user should be redirected to the edit endpoint
of the new page."""
with self.login_user_context(self.admin):
# add page
page_data = {
'title': 'another page', 'slug': 'type1', 'template': 'nav_playground.html',
'language': 'en',
'edit': 1,
}
self.assertEqual(Page.objects.all().count(), 1)
response = self.client.post(
self.get_admin_url(PageContent, 'add'),
data=page_data,
)
redirect_url = get_object_edit_url(PageContent.objects.get(title='another page'))
self.assertContains(response, f'href="{redirect_url}"')
self.assertEqual(Page.objects.all().count(), 2)

def test_add_page_no_redirect(self):
with self.login_user_context(self.admin):
# add page
page_data = {
'title': 'another page', 'slug': 'type1', 'template': 'nav_playground.html',
'language': 'en',
'edit': 0,
}
self.assertEqual(Page.objects.all().count(), 1)
response = self.client.post(
self.get_admin_url(PageContent, 'add'),
data=page_data,
)
redirect_url = self.get_admin_url(PageContent, 'changelist') + "?language=en"
self.assertRedirects(response, redirect_url)
self.assertEqual(Page.objects.all().count(), 2)

class PermissionsTestCase(PageTestBase):

def _add_translation_to_page(self, page):
Expand Down Expand Up @@ -2912,7 +2958,7 @@ def test_user_can_copy_plugins_to_language(self):
"""
page = self.get_permissions_test_page()
staff_user = self.get_staff_user_with_no_permissions()
source_translation = self.get_page_title_obj(page, 'en')
source_translation = self.get_pagecontent_obj(page, 'en')
target_translation = self._add_translation_to_page(page)
endpoint = self.get_admin_url(PageContent, 'copy_language', source_translation.pk)
plugins = [
Expand Down Expand Up @@ -4320,7 +4366,7 @@ def test_user_can_copy_plugins_to_language(self):
"""
page = self._permissions_page
staff_user = self.get_staff_user_with_no_permissions()
source_translation = self.get_page_title_obj(page, 'en')
source_translation = self.get_pagecontent_obj(page, 'en')
target_translation = self._add_translation_to_page(page)
endpoint = self.get_admin_url(PageContent, 'copy_language', source_translation.pk)
plugins = [
Expand Down
6 changes: 3 additions & 3 deletions cms/tests/test_placeholder.py
Expand Up @@ -879,7 +879,7 @@ def test_sets_source_when_title_is_created(self):
page = create_page('test page en', 'col_two.html', 'en')

# check for en
page_content_en = self.get_page_title_obj(page)
page_content_en = self.get_pagecontent_obj(page)
self.assertQuerySetEqual(
Placeholder.objects.get_for_obj(page_content_en),
page_content_en.get_placeholders(),
Expand All @@ -906,8 +906,8 @@ def test_sets_source_when_title_is_copied(self):
with self.login_user_context(self.get_superuser()):
new_page = self.copy_page(page, page, position=1)

page_content = self.get_page_title_obj(page)
new_page_content = self.get_page_title_obj(new_page)
page_content = self.get_pagecontent_obj(page)
new_page_content = self.get_pagecontent_obj(new_page)
page_content_plhs = Placeholder.objects.get_for_obj(page_content)
new_page_content_plhs = Placeholder.objects.get_for_obj(new_page_content)
self.assertEqual(page_content_plhs.count(), new_page_content_plhs.count())
Expand Down
2 changes: 1 addition & 1 deletion cms/tests/test_plugins.py
Expand Up @@ -816,7 +816,7 @@ def test_plugin_toolbar_struct(self):

def test_plugin_toolbar_struct_permissions(self):
page = self.get_permissions_test_page()
page_content = self.get_page_title_obj(page)
page_content = self.get_pagecontent_obj(page)
page_edit_url = get_object_edit_url(page_content)
staff_user = self.get_staff_user_with_no_permissions()
placeholder = page.get_placeholders('en').get(slot='body')
Expand Down
4 changes: 2 additions & 2 deletions cms/tests/test_rendering.py
Expand Up @@ -734,7 +734,7 @@ def test_render_placeholder_toolbar(self):
placeholder.pk = placeholder.id = 99

with self.login_user_context(self.get_superuser()):
page_content = self.get_page_title_obj(self.test_page)
page_content = self.get_pagecontent_obj(self.test_page)
request = self.get_request(get_object_edit_url(page_content))
request.session = {}
request.toolbar = CMSToolbar(request)
Expand Down Expand Up @@ -771,7 +771,7 @@ def test_render_plugin_toolbar_markup(self):
]

with self.login_user_context(self.get_superuser()):
page_content = self.get_page_title_obj(page)
page_content = self.get_pagecontent_obj(page)
request = self.get_request(get_object_edit_url(page_content))
request.session = {}
request.toolbar = CMSToolbar(request)
Expand Down
2 changes: 1 addition & 1 deletion cms/tests/test_static_analysis.py
Expand Up @@ -10,4 +10,4 @@ class AboveStaticAnalysisCodeTest(TestCase):
"""
def test_ruff(self):
ruff = find_ruff_bin()
self.assertEqual(os.spawnv(os.P_WAIT, ruff, ["ruff", "cms", "menus"]), 0)
self.assertEqual(os.spawnv(os.P_WAIT, ruff, ["ruff", "check", "cms", "menus"]), 0)

0 comments on commit c96d96f

Please sign in to comment.