From a94b72cd8d9b8fbe0d4c45649bd6eddd6af366df Mon Sep 17 00:00:00 2001 From: Joshua Jonah Date: Wed, 5 Oct 2016 15:44:17 -0400 Subject: [PATCH 1/4] Added `FEINCMS_ALLOW_EXTRA_PATH_PREFIX` to allow arbitrary url prefixes to be ignored. In my case this was for a middleware which added language prefixes. --- docs/settings.rst | 5 +++++ feincms/module/page/models.py | 4 ++++ tests/testapp/tests/test_page.py | 18 +++++++++++++++--- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 47f4ffeb2..5291f1aa4 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -72,6 +72,11 @@ by :mod:`feincms.module.page`. random gunk after a valid page URL. The standard behavior is to raise a 404 if extra path elements aren't handled by a content type's ``process()`` method. +``FEINCMS_ALLOW_EXTRA_PATH_PREFIX``: Defaults to ``()``. Define a tuple of +strings to allow predetermined url prefixes to be ignored. The standard behavior +is to raise a 404 if extra path elements aren't handled by a content type's +``process()`` method. + ``FEINCMS_TRANSLATION_POLICY``: Defaults to ``STANDARD``. How to switch languages. diff --git a/feincms/module/page/models.py b/feincms/module/page/models.py index 933fd5822..19941c6d9 100644 --- a/feincms/module/page/models.py +++ b/feincms/module/page/models.py @@ -74,6 +74,10 @@ def best_match_for_path(self, path, raise404=False): paths = ['/'] path = path.strip('/') + for prefix in settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX: + if path.startswith('%s/' % prefix): + path = path[len(prefix)+1:] + if path: tokens = path.split('/') paths += [ diff --git a/tests/testapp/tests/test_page.py b/tests/testapp/tests/test_page.py index 863424db5..e13abb85a 100644 --- a/tests/testapp/tests/test_page.py +++ b/tests/testapp/tests/test_page.py @@ -1063,19 +1063,31 @@ def test_19_page_manager(self): Page.objects.best_match_for_path( page.get_absolute_url() + 'something/hello/')) + # test `FEINCMS_ALLOW_EXTRA_PATH` old = feincms_settings.FEINCMS_ALLOW_EXTRA_PATH - request.path += 'hello/' + test_path = '%shello/' % request.path feincms_settings.FEINCMS_ALLOW_EXTRA_PATH = False - self.assertEqual(self.client.get(request.path).status_code, 404) + self.assertEqual(self.client.get(test_path).status_code, 404) feincms_settings.FEINCMS_ALLOW_EXTRA_PATH = True - self.assertEqual(self.client.get(request.path).status_code, 200) + self.assertEqual(self.client.get(test_path).status_code, 200) self.assertEqual( page, Page.objects.for_request(request, best_match=True)) feincms_settings.FEINCMS_ALLOW_EXTRA_PATH = old + # test FEINCMS_ALLOW_EXTRA_PATH_PREFIX + old = feincms_settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX + test_path = 'prefix%s' % request.path + + feincms_settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX = ('prefix',) + self.assertEqual(self.client.get(request.path).status_code, 200) + self.assertEqual( + page, Page.objects.for_request(request, best_match=True)) + + feincms_settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX = old + page_id = id(request._feincms_page) p = Page.objects.for_request(request) self.assertEqual(id(p), page_id) From b075a2431ca5285b496e654ec95d1854e3a8b2b2 Mon Sep 17 00:00:00 2001 From: Joshua Jonah Date: Wed, 5 Oct 2016 15:50:34 -0400 Subject: [PATCH 2/4] Added a default setting. --- feincms/default_settings.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/feincms/default_settings.py b/feincms/default_settings.py index 3147ae1a3..957473c3c 100644 --- a/feincms/default_settings.py +++ b/feincms/default_settings.py @@ -90,6 +90,16 @@ 'FEINCMS_ALLOW_EXTRA_PATH', False) +# ------------------------------------------------------------------------ +#: Allow random prefixes to be ignored when using +#: `Page.best_match_for_path()` and the `add_page_if_missing` context +#: processor. +#: Defaults to an empty tuple. +FEINCMS_ALLOW_EXTRA_PATH_PREFIX = getattr( + settings, + 'FEINCMS_ALLOW_EXTRA_PATH_PREFIX', + ()) + # ------------------------------------------------------------------------ #: How to switch languages. #: * ``'STANDARD'``: The page a user navigates to sets the site's language From 50d24228fc417652d6afdf50f37a151046bf3bf4 Mon Sep 17 00:00:00 2001 From: Joshua Jonah Date: Wed, 5 Oct 2016 16:28:14 -0400 Subject: [PATCH 3/4] Modified test to work. It was not possible to change the setting when the model manager was instanciated at startup. --- feincms/module/page/models.py | 2 +- tests/testapp/tests/test_page.py | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/feincms/module/page/models.py b/feincms/module/page/models.py index 19941c6d9..945812f6d 100644 --- a/feincms/module/page/models.py +++ b/feincms/module/page/models.py @@ -73,7 +73,7 @@ def best_match_for_path(self, path, raise404=False): paths = ['/'] path = path.strip('/') - + for prefix in settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX: if path.startswith('%s/' % prefix): path = path[len(prefix)+1:] diff --git a/tests/testapp/tests/test_page.py b/tests/testapp/tests/test_page.py index e13abb85a..33e4ac234 100644 --- a/tests/testapp/tests/test_page.py +++ b/tests/testapp/tests/test_page.py @@ -1065,28 +1065,37 @@ def test_19_page_manager(self): # test `FEINCMS_ALLOW_EXTRA_PATH` old = feincms_settings.FEINCMS_ALLOW_EXTRA_PATH - test_path = '%shello/' % request.path + old_path = request.path + request.path += 'hello/' feincms_settings.FEINCMS_ALLOW_EXTRA_PATH = False - self.assertEqual(self.client.get(test_path).status_code, 404) + self.assertEqual(self.client.get(request.path).status_code, 404) feincms_settings.FEINCMS_ALLOW_EXTRA_PATH = True - self.assertEqual(self.client.get(test_path).status_code, 200) + self.assertEqual(self.client.get(request.path).status_code, 200) self.assertEqual( page, Page.objects.for_request(request, best_match=True)) feincms_settings.FEINCMS_ALLOW_EXTRA_PATH = old + request.path = old_path # test FEINCMS_ALLOW_EXTRA_PATH_PREFIX old = feincms_settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX - test_path = 'prefix%s' % request.path + old_path = request.path + request.path = 'prefix' + request.path + + feincms_settings.FEINCMS_ALLOW_EXTRA_PATH = () + self.assertRaises( + Page.DoesNotExist, + lambda: Page.objects.best_match_for_path(request.path)) feincms_settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX = ('prefix',) - self.assertEqual(self.client.get(request.path).status_code, 200) - self.assertEqual( - page, Page.objects.for_request(request, best_match=True)) + self.assertIsInstance( + Page.objects.best_match_for_path(request.path), + Page) feincms_settings.FEINCMS_ALLOW_EXTRA_PATH_PREFIX = old + request.path = old_path page_id = id(request._feincms_page) p = Page.objects.for_request(request) From ec8e3c46b1b87fa1499cdb477f4c2a2826b38fa1 Mon Sep 17 00:00:00 2001 From: Joshua Jonah Date: Wed, 5 Oct 2016 16:51:31 -0400 Subject: [PATCH 4/4] Changed `ALL_APPS_CONFIG` to a `collections.OrderedDict` to stop random order when populating `urlconf_path` choices attribute. This was causing a new migrations being created randomly as the `cls.ALL_APPS_CONFIG.values()` call was not consistent. --- feincms/content/application/models.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feincms/content/application/models.py b/feincms/content/application/models.py index 4f3a215a1..b0ba5462b 100644 --- a/feincms/content/application/models.py +++ b/feincms/content/application/models.py @@ -1,5 +1,6 @@ from __future__ import absolute_import +from collections import OrderedDict from email.utils import parsedate from functools import partial, wraps from time import mktime @@ -171,7 +172,7 @@ class ApplicationContent(models.Model): # MyBlogApp for blog ") parameters = JSONField(null=True, editable=False) - ALL_APPS_CONFIG = {} + ALL_APPS_CONFIG = OrderedDict() class Meta: abstract = True