From 952504e76c285e27e062cc0e2b4cefa54b0db59a Mon Sep 17 00:00:00 2001 From: Ivo Branco Date: Wed, 25 Jan 2023 12:05:45 +0000 Subject: [PATCH] feat: add setting so redirect preserve params Added a new setting that allow to configure globally if the django-cms redirects preserving the query parameters. `REDIRECT_PRESERVE_QUERY_PARAMS`. This feature is usefull for example: 1. marketing campains extra parameters, 2. social networks extra parameters like `fbclick`, 3. custom developed parameters, after that page has been moved, the older URLs for that page should preserve the functionality. --- cms/tests/test_views.py | 25 +++++++++++++++++++++++++ cms/utils/conf.py | 1 + cms/views.py | 4 ++++ docs/reference/configuration.rst | 10 ++++++++++ 4 files changed, 40 insertions(+) diff --git a/cms/tests/test_views.py b/cms/tests/test_views.py index b90725743b2..9d80d20d6ad 100644 --- a/cms/tests/test_views.py +++ b/cms/tests/test_views.py @@ -152,6 +152,31 @@ def test_redirect_with_toolbar(self): response = self.client.get(self.get_toolbar_disable_url(page_url)) self.assertEqual(response.status_code, 302) + def test_redirect_not_preserving_query_parameters(self): + # test redirect checking that the query parameters aren't preserved + redirect = '/en/' + one = create_page("one", "nav_playground.html", "en", published=True, + redirect=redirect) + url = one.get_absolute_url() + params = "?param_name=param_value" + request = self.get_request(url + params) + response = details(request, one.get_path()) + self.assertEqual(response.status_code, 302) + self.assertEqual(response['Location'], redirect) + + @override_settings(CMS_REDIRECT_PRESERVE_QUERY_PARAMS=True) + def test_redirect_preserving_query_parameters(self): + # test redirect checking that query parameters are preserved + redirect = '/en/' + one = create_page("one", "nav_playground.html", "en", published=True, + redirect=redirect) + url = one.get_absolute_url() + params = "?param_name=param_value" + request = self.get_request(url + params) + response = details(request, one.get_path()) + self.assertEqual(response.status_code, 302) + self.assertEqual(response['Location'], redirect + params) + def test_login_required(self): self.create_homepage("page", "nav_playground.html", "en", published=True, login_required=True) plain_url = '/accounts/' diff --git a/cms/utils/conf.py b/cms/utils/conf.py index 22b33b5a726..d3863f3a4ac 100644 --- a/cms/utils/conf.py +++ b/cms/utils/conf.py @@ -89,6 +89,7 @@ def wrapper(): ), 'COLOR_SCHEME': 'light', 'COLOR_SCHEME_TOGGLE': False, + 'REDIRECT_PRESERVE_QUERY_PARAMS': False, } diff --git a/cms/views.py b/cms/views.py index 6343ae2bf59..89c80c377b7 100644 --- a/cms/views.py +++ b/cms/views.py @@ -162,6 +162,10 @@ def details(request, slug): toolbar.redirect_url = redirect_url elif redirect_url not in own_urls: # prevent redirect to self + if get_cms_setting('REDIRECT_PRESERVE_QUERY_PARAMS'): + query_string = request.META.get('QUERY_STRING') + if query_string: + redirect_url += "?" + query_string return HttpResponseRedirect(redirect_url) # permission checks diff --git a/docs/reference/configuration.rst b/docs/reference/configuration.rst index 08d0ff1301b..a630c28d2fd 100644 --- a/docs/reference/configuration.rst +++ b/docs/reference/configuration.rst @@ -1190,3 +1190,13 @@ when the "Content" field is filled in. There should be no need to change it, unless you **don't** use ``djangocms-text-ckeditor`` in your project **and** your custom plugin defined in :setting:`CMS_PAGE_WIZARD_CONTENT_PLUGIN` have a body field **different** than ``body``. + +.. setting:: CMS_REDIRECT_PRESERVE_QUERY_PARAMS + +CMS_REDIRECT_PRESERVE_QUERY_PARAMS +=================================== + +default + ``False`` + +This indicates to the CMS that redirects should preserve the query parameters.