123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- .. _frontend_cache_purging:
- Frontend cache invalidator
- ==========================
- .. versionchanged:: 0.7
- * Multiple backend support added
- * Cloudflare support added
- .. versionchanged:: 1.7
- * Amazon CloudFront support added
- Many websites use a frontend cache such as Varnish, Squid, Cloudflare or CloudFront to gain extra performance. The downside of using a frontend cache though is that they don't respond well to updating content and will often keep an old version of a page cached after it has been updated.
- This document describes how to configure Wagtail to purge old versions of pages from a frontend cache whenever a page gets updated.
- Setting it up
- -------------
- Firstly, add ``"wagtail.contrib.wagtailfrontendcache"`` to your INSTALLED_APPS:
- .. code-block:: python
- INSTALLED_APPS = [
- ...
- "wagtail.contrib.wagtailfrontendcache"
- ]
- .. versionchanged:: 0.8
- Signal handlers are now automatically registered
- The ``wagtailfrontendcache`` module provides a set of signal handlers which will automatically purge the cache whenever a page is published or deleted. These signal handlers are automatically registered when the ``wagtail.contrib.wagtailfrontendcache`` app is loaded.
- Varnish/Squid
- ^^^^^^^^^^^^^
- Add a new item into the ``WAGTAILFRONTENDCACHE`` setting and set the ``BACKEND`` parameter to ``wagtail.contrib.wagtailfrontendcache.backends.HTTPBackend``. This backend requires an extra parameter ``LOCATION`` which points to where the cache is running (this must be a direct connection to the server and cannot go through another proxy).
- .. code-block:: python
- # settings.py
- WAGTAILFRONTENDCACHE = {
- 'varnish': {
- 'BACKEND': 'wagtail.contrib.wagtailfrontendcache.backends.HTTPBackend',
- 'LOCATION': 'http://localhost:8000',
- },
- }
- Finally, make sure you have configured your frontend cache to accept PURGE requests:
- - `Varnish <https://www.varnish-cache.org/docs/3.0/tutorial/purging.html>`_
- - `Squid <http://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F>`_
- .. _frontendcache_cloudflare:
- Cloudflare
- ^^^^^^^^^^
- Firstly, you need to register an account with Cloudflare if you haven't already got one. You can do this here: `Cloudflare Sign up <https://www.cloudflare.com/sign-up>`_
- Add an item into the ``WAGTAILFRONTENDCACHE`` and set the ``BACKEND`` parameter to ``wagtail.contrib.wagtailfrontendcache.backends.CloudflareBackend``. This backend requires three extra parameters, ``EMAIL`` (your Cloudflare account email), ``TOKEN`` (your API token from Cloudflare), and ``ZONEID`` (for zone id for your domain, see below).
- To find the ``ZONEID`` for your domain, read the `Cloudflare API Documentation <https://api.cloudflare.com/#getting-started-resource-ids>`_
- .. code-block:: python
- # settings.py
- WAGTAILFRONTENDCACHE = {
- 'cloudflare': {
- 'BACKEND': 'wagtail.contrib.wagtailfrontendcache.backends.CloudflareBackend',
- 'EMAIL': 'your-cloudflare-email-address@example.com',
- 'TOKEN': 'your cloudflare api token',
- 'ZONEID': 'your cloudflare domain zone id',
- },
- }
- .. _frontendcache_aws_cloudfront:
- Amazon CloudFront
- ^^^^^^^^^^^^^^^^^
- Within Amazon Web Services you will need at least one CloudFront web distribution. If you don't have one, you can get one here: `CloudFront getting started <https://aws.amazon.com/cloudfront/>`_
- Add an item into the ``WAGTAILFRONTENDCACHE`` and set the ``BACKEND`` parameter to ``wagtail.contrib.wagtailfrontendcache.backends.CloudfrontBackend``. This backend requires one extra parameter, ``DISTRIBUTION_ID`` (your CloudFront generated distribution id).
- .. code-block:: python
- WAGTAILFRONTENDCACHE = {
- 'cloudfront': {
- 'BACKEND': 'wagtail.contrib.wagtailfrontendcache.backends.CloudfrontBackend',
- 'DISTRIBUTION_ID': 'your-distribution-id',
- },
- }
- Configuration of credentials can done in multiple ways. You won't need to store them in your Django settings file. You can read more about this here: `Boto 3 Docs <http://boto3.readthedocs.org/en/latest/guide/configuration.html>`_
- In case you run multiple sites with Wagtail and each site has its CloudFront distribution, provide a mapping instead of a single distribution. Make sure the mapping matches with the hostnames provided in your site settings.
- .. code-block:: python
- WAGTAILFRONTENDCACHE = {
- 'cloudfront': {
- 'BACKEND': 'wagtail.contrib.wagtailfrontendcache.backends.CloudfrontBackend',
- 'DISTRIBUTION_ID': {
- 'www.wagtail.io': 'your-distribution-id',
- 'www.madewithwagtail.org': 'your-distribution-id',
- },
- },
- }
- .. note::
- In most cases, absolute URLs with ``www`` prefixed domain names should be used in your mapping. Only drop the ``www`` prefix if you're absolutely sure you're not using it (e.g. a subdomain).
- Advanced usage
- --------------
- Invalidating more than one URL per page
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- By default, Wagtail will only purge one URL per page. If your page has more than one URL to be purged, you will need to override the ``get_cached_paths`` method on your page type.
- .. code-block:: python
- class BlogIndexPage(Page):
- def get_blog_items(self):
- # This returns a Django paginator of blog items in this section
- return Paginator(self.get_children().live().type(BlogPage), 10)
- def get_cached_paths(self):
- # Yield the main URL
- yield '/'
- # Yield one URL per page in the paginator to make sure all pages are purged
- for page_number in range(1, self.get_blog_items().num_pages + 1):
- yield '/?page=' + str(page_number)
- Invalidating index pages
- ^^^^^^^^^^^^^^^^^^^^^^^^
- Another problem is pages that list other pages (such as a blog index) will not be purged when a blog entry gets added, changed or deleted. You may want to purge the blog index page so the updates are added into the listing quickly.
- This can be solved by using the ``purge_page_from_cache`` utility function which can be found in the ``wagtail.contrib.wagtailfrontendcache.utils`` module.
- Let's take the the above BlogIndexPage as an example. We need to register a signal handler to run when one of the BlogPages get updated/deleted. This signal handler should call the ``purge_page_from_cache`` function on all BlogIndexPages that contain the BlogPage being updated/deleted.
- .. code-block:: python
- # models.py
- from django.dispatch import receiver
- from django.db.models.signals import pre_delete
- from wagtail.wagtailcore.signals import page_published
- from wagtail.contrib.wagtailfrontendcache.utils import purge_page_from_cache
- ...
- def blog_page_changed(blog_page):
- # Find all the live BlogIndexPages that contain this blog_page
- for blog_index in BlogIndexPage.objects.live():
- if blog_page in blog_index.get_blog_items().object_list:
- # Purge this blog index
- purge_page_from_cache(blog_index)
- @receiver(page_published, sender=BlogPage):
- def blog_published_handler(instance):
- blog_page_changed(instance)
- @receiver(pre_delete, sender=BlogPage)
- def blog_deleted_handler(instance):
- blog_page_changed(instance)
- Invalidating individual URLs
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- ``wagtail.contrib.wagtailfrontendcache.utils`` provides another function called ``purge_url_from_cache``. As the name suggests, this purges an individual URL from the cache.
- For example, this could be useful for purging a single page of blogs:
- .. code-block:: python
- from wagtail.contrib.wagtailfrontendcache.utils import purge_url_from_cache
- # Purge the first page of the blog index
- purge_url_from_cache(blog_index.url + '?page=1')
|