Repository: wagtail/wagtail

Issue:
Wagtail admin static assets should be cache busted to prevent outdated cache issues
### Issue Summary

When Wagtail is updated, the admin UI should work without the user having to clean their cache. #3693 is an example of this problem, where a release contains a lot of changes to the static JS and CSS of the admin interface. Servers/browsers that have caching enabled will serve the cached files from the previous version, producing a broken UI.

This could be prevented by implementing cache busting by renaming the URLs to the static assets (this is most commonly done with a query string suffix containing a version number, or hash of the files' content).

### Steps to Reproduce

1. Install a project with Wagtail 1.10 and navigate to its admin, open the page explorer menu.
2. Upgrade the project to Wagtail 1.11 and do the same operation.

Expectation: Updates should "just work" for end users of the product, who may not even be aware of the update.

### Technical details

- Any Wagtail upgrade that includes changes to static files (eg. 1.10 to 1.11)
- Browser / proxy / server combinations that have caching enabled

---

Any advice on how best to do this in a Django codebase is very welcome.


Discussion:
As we discussed on the Slack team, a perfect solution is to use [ManifestStaticFilesStorage](https://docs.djangoproject.com/en/1.11/ref/contrib/staticfiles/#manifeststaticfilesstorage). It automatically adds a hash on all static files to make sure it’s the right version.

I think we should definitely tell people to use it in the docs, as well as including it in the project creation template. Otherwise, we’ll keep getting reports each time we change JS or CSS.
That's exactly what we need! I'm not sure I understand the details, if this is only an opt-in I'm afraid there will still be a lot of instances where people don't read the docs and get burnt. Can usage be enforced for the Wagtail apps only?
We can enforce it, but I don’t think that’s a nice way to do it, as other apps may rely on a different static files storage. We can add a warning, however.
Hey, interesting approach. 
From experience, making any kind of change from Django's default setup (even something as innocent as splitting settings into base/dev/production) tends to cause confusion or disruption to users one way or another. I'm not fully confident that enabling ManifestStaticFilesStorage won't have unexpected side effects on some setups (e.g. when static assets are hosted remotely), and I'd be happier for this to be something that developers have to consciously enable themselves.

I'd propose having a section in the [deployment](http://docs.wagtail.io/en/latest/advanced_topics/deploying.html) docs covering this, along with a brief pointer on the [upgrading](http://docs.wagtail.io/en/latest/releases/upgrading.html) page.
I'm worried that documentation will be overlooked / and that those specific setups that can't leverage ManifestStaticFilesStorage will still have the issue. Even though cache busting is a known practice, and easily covered in most frameworks, it still is a very common issue for end users to arrive on half-broken UIs because it's been overlooked.

Would it be reasonable to make a custom tag that automatically adds Wagtail's version number in a query string at the end of the URL of static files?
See also https://stackoverflow.com/questions/49088302/richtextfield-uneditable-with-draftail-in-wagtail-2-0.

I only expect this to become more frequent of a problem as Wagtail updates integrate more client-side changes. It would be great if it "just worked" by default – at the moment any kind of issue of this type is too easily classified as "Wagtail's new version is broken".
I was thinking about integrate new `Draftail` plugins in a project: i mean, we would have to install in in the `static_src` and recompile admin static files, isn't it? 
@SalahAdDin no – please have a look at the [official docs](http://docs.wagtail.io/en/v2.0/advanced_topics/customisation/extending_draftail.html#creating-new-entities). And let's keep this issue about cache busting.

Resolving patch:
diff --git a/wagtail/project_template/project_name/settings/base.py b/wagtail/project_template/project_name/settings/base.py
--- a/wagtail/project_template/project_name/settings/base.py
+++ b/wagtail/project_template/project_name/settings/base.py
@@ -142,6 +142,11 @@
     os.path.join(PROJECT_DIR, 'static'),
 ]
 
+# ManifestStaticFilesStorage is recommended in production, to prevent outdated
+# Javascript / CSS assets being served from cache (e.g. after a Wagtail upgrade).
+# See https://docs.djangoproject.com/en/{{ docs_version }}/ref/contrib/staticfiles/#manifeststaticfilesstorage
+STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
+
 STATIC_ROOT = os.path.join(BASE_DIR, 'static')
 STATIC_URL = '/static/'
 


Test patch: