From b3fa09b95ed7474a3307a6afa317e0d504e2fc86 Mon Sep 17 00:00:00 2001 From: pyMan Date: Wed, 25 Oct 2017 17:34:48 +0100 Subject: [PATCH] Improved 'purge_page_from_cache' to purge the url for any managed language --- CHANGELOG.txt | 1 + docs/reference/contrib/frontendcache.rst | 3 ++ docs/releases/2.1.rst | 1 + wagtail/contrib/frontend_cache/tests.py | 12 ++++++++ wagtail/contrib/frontend_cache/utils.py | 36 ++++++++++++++++++++++-- wagtail/tests/urls_multilang.py | 9 ++++++ 6 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 wagtail/tests/urls_multilang.py diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1515aaf8f3..5a37b946cc 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -24,6 +24,7 @@ Changelog * Add new `wagtail_icon` template tag to facilitate making admin icons accessible (Sander Tuit) * Set `ALLOWED_HOSTS` in the project template to allow any host in development (Tom Dyson) * Expose reusable client-side code to build Draftail extensions (Thibaud Colas) + * Added `WAGTAILFRONTENDCACHE_LANGUAGES` setting to specify the languages whose URLs are to be purged when using `i18n_patterns` (PyMan Claudio Marinozzi) * Fix: Status button on 'edit page' now links to the correct URL when live and draft slug differ (LB (Ben Johnston)) * Fix: Image title text in the gallery and in the chooser now wraps for long filenames (LB (Ben Johnston), Luiz Boaretto) * Fix: Move image editor action buttons to the bottom of the form on mobile (Julian Gallo) diff --git a/docs/reference/contrib/frontendcache.rst b/docs/reference/contrib/frontendcache.rst index 3c02b15d6a..419fa7afe1 100644 --- a/docs/reference/contrib/frontendcache.rst +++ b/docs/reference/contrib/frontendcache.rst @@ -52,8 +52,11 @@ Add a new item into the ``WAGTAILFRONTENDCACHE`` setting and set the ``BACKEND`` 'LOCATION': 'http://localhost:8000', }, } + WAGTAILFRONTENDCACHE_LANGUAGES = [] +Set ``WAGTAILFRONTENDCACHE_LANGUAGES`` to a list of languages (typically equal to ``[l[0] for l in settings.LANGUAGES]``) to also purge the urls for each language of a purging url. This setting needs ``settings.USE_I18N`` to be ``True`` to work. Its default is an empty list. + Finally, make sure you have configured your frontend cache to accept PURGE requests: - `Varnish `_ diff --git a/docs/releases/2.1.rst b/docs/releases/2.1.rst index 159cffe010..fd746357b4 100644 --- a/docs/releases/2.1.rst +++ b/docs/releases/2.1.rst @@ -43,6 +43,7 @@ Other features * Add new `wagtail_icon` template tag to facilitate making admin icons accessible (Sander Tuit) * Set `ALLOWED_HOSTS` in the project template to allow any host in development (Tom Dyson) * Expose reusable client-side code to build Draftail extensions (Thibaud Colas) + * Added ``WAGTAILFRONTENDCACHE_LANGUAGES`` setting to specify the languages whose URLs are to be purged when using ``i18n_patterns`` (PyMan Claudio Marinozzi) Bug fixes ~~~~~~~~~ diff --git a/wagtail/contrib/frontend_cache/tests.py b/wagtail/contrib/frontend_cache/tests.py index c178a854fe..9cda4d4b84 100644 --- a/wagtail/contrib/frontend_cache/tests.py +++ b/wagtail/contrib/frontend_cache/tests.py @@ -209,6 +209,18 @@ class TestCachePurgingSignals(TestCase): page.save_revision().publish() self.assertEqual(PURGED_URLS, []) + @override_settings(ROOT_URLCONF='wagtail.tests.urls_multilang', + LANGUAGE_CODE='en', + WAGTAILFRONTENDCACHE_LANGUAGES=['en']) + def test_purge_on_publish_in_multilang_env(self): + from django.conf import settings + PURGED_URLS[:] = [] # reset PURGED_URLS to the empty list + page = EventIndex.objects.get(url_path='/home/events/') + page.save_revision().publish() + self.assertEqual(len(PURGED_URLS), len(settings.WAGTAILFRONTENDCACHE_LANGUAGES) * 2) + for isocode, description in settings.WAGTAILFRONTENDCACHE_LANGUAGES: + self.assertIn('http://localhost/%s/events/' % isocode, PURGED_URLS) + class TestPurgeBatchClass(TestCase): # Tests the .add_*() methods on PurgeBatch. The .purge() method is tested diff --git a/wagtail/contrib/frontend_cache/utils.py b/wagtail/contrib/frontend_cache/utils.py index e6af3cd114..1d2450307f 100644 --- a/wagtail/contrib/frontend_cache/utils.py +++ b/wagtail/contrib/frontend_cache/utils.py @@ -1,8 +1,10 @@ import logging +import re from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.utils.module_loading import import_string +from django.utils.six.moves.urllib.parse import urlparse, urlunparse logger = logging.getLogger('wagtail.frontendcache') @@ -54,12 +56,40 @@ def get_backends(backend_settings=None, backends=None): def purge_url_from_cache(url, backend_settings=None, backends=None): - for backend_name, backend in get_backends(backend_settings, backends).items(): - logger.info("[%s] Purging URL: %s", backend_name, url) - backend.purge(url) + purge_urls_from_cache([url], backend_settings=backend_settings, backends=backends) def purge_urls_from_cache(urls, backend_settings=None, backends=None): + # Convert each url to urls one for each managed language (WAGTAILFRONTENDCACHE_LANGUAGES setting). + # The managed languages are common to all the defined backends. + # This depends on settings.USE_I18N + languages = getattr(settings, 'WAGTAILFRONTENDCACHE_LANGUAGES', []) + if settings.USE_I18N and languages: + langs_regex = "^/(%s)/" % "|".join(languages) + new_urls = [] + + # Purge the given url for each managed language + for isocode, description in languages: + for url in urls: + up = urlparse(url) + new_url = urlunparse(( + up.scheme, + up.netloc, + re.sub(langs_regex, "/%s/" % isocode, up.path), + up.params, + up.query, + up.fragment + )) + + # Check for best performance. True if re.sub found no match + # It happens when i18n_patterns was not used in urls.py to serve content for different languages from different URLs + if new_url in new_urls: + continue + + new_urls.append(new_url) + + urls = new_urls + for backend_name, backend in get_backends(backend_settings, backends).items(): for url in urls: logger.info("[%s] Purging URL: %s", backend_name, url) diff --git a/wagtail/tests/urls_multilang.py b/wagtail/tests/urls_multilang.py new file mode 100644 index 0000000000..caba09fa4d --- /dev/null +++ b/wagtail/tests/urls_multilang.py @@ -0,0 +1,9 @@ +from __future__ import absolute_import, unicode_literals + +from django.conf.urls import include, url +from django.conf.urls.i18n import i18n_patterns + +from wagtail.core import urls as wagtail_urls + + +urlpatterns = i18n_patterns(url(r'', include(wagtail_urls)))