Basic Usage¶
Django Manifest Loader comes with two template tags that house all logic. The manifest tag takes a single string
input, such as 'main.js', looks it up against the webpack manifest, and then outputs the URL to that compiled file.
It works just like Django’s built it static tag, except it’s finding the filename according to your manifest file.
The manifest_match tag takes two arguments, a string to pattern match filenames against and a string to embed matched file urls into. See the manifest_match section for more information.
Manifest tag¶
{% load manifest %}
<script src="{% manifest 'main.js' %}"></script>
turns into
<script src="/static/main.8f7705adfa281590b8dd.js"></script>
Where the argument to the tag will be the original filename of a file processed by webpack. If in doubt, check your
manifest.json file generated by webpack to see what files are available.
This is worthwhile because of the content hash after the original filename, which will invalidate the browser cache every time the file is updated, which will ensure that your users always have the latest assets.
Manifest match tag¶
{% load manifest %}
{% manifest_match '*.js' '<script src="{match}"></script>' %}
turns into
<script src="/static/vendors~main.3ad032adfa281590f2a21.js"></script>
<script src="/static/main.8f7705adfa281590b8dd.js"></script>
This tag takes two arguments, a pattern to match against, according to the python fnmatch package rules,
and a string to input the file URLs into. The second argument must contain the string {match}, as it is replaced with the URLs.
Advanced Usage¶
Use as Jinja template filter¶
Use with django-jinja is very similar to usage with Django templating. In the jinja configuration you need to point
to the filters like:
# settings.py
TEMPLATES = [
{
"BACKEND": "django_jinja.backend.Jinja2",
"OPTIONS": {
"filters": {
"manifest": "manifest_loader.utils.manifest",
"manifest_match": "manifest_loader.utils.manifest_match",
}
}
},
]
The manifest filter takes a single argument:
<script src="{{ 'main.js'|manifest }}"></script>
And the manifest match filter:
{{ '*.js'|manifest_match('<script src="{match}"></script>') }}
All other instructions in this documentation should be followed as normal.
Use outside of templates¶
If you need the functions of the manifest and manifest_match template tags, you can import their core logic into
your python project and use them exactly as you would in your templates.
>>> # register django settings if using in python console
>>> from manifest_loader.utils import manifest, manifest_match
>>>
>>> manifest('main.js')
'/static/main.e12dfe2f9b185dea03a4.js'
>>>
>>> manifest_match('*.js', '{match}')
'/static/main.e12dfe2f9b185dea03a4.js\n/static/chunk1.hash.js\n/static/chunk2.hash.js\n/static/chunk3.hash.js'
Custom Loaders¶
Custom loaders allow you to implement your own means of extracting data from your manifest file. If your manifest
file is not the default structure of webpack manifest plugin, this is how you can tell django-manifest-loader how to read it.
First import the loader parent abstract class, and subclass it in your new loader class.
from manifest_loader.loaders import LoaderABC
class MyCustomLoader(LoaderABC):
Your new loader must have two static methods that each take two required arguments:
get_single_match(manifest, key) and get_multi_match(manifest, pattern).
from manifest_loader.loaders import LoaderABC
class MyCustomLoader(LoaderABC):
@staticmethod
def get_single_match(manifest, key):
pass
@staticmethod
def get_multi_match(manifest, pattern):
pass
get_single_match- returns aString, finds a single file in your manifest file, according to thekeyget_multi_match- returns aListof files in your manifest, according to thepatternmanifest- this is your full manifest file, after being processed byjson.load(). It will be a dictionary or list depending on which it is in your manifest file.key-String; the argument passed into themanifesttemplate tag. e.g.: in the template tag{% manifest 'index.js' %}, the string'index.js'is sent toget_single_matchaskey(without surrounding quotes)pattern-String; the first argument passed into themanifest_matchtemplate tag. e.g.: in the template tag{% manifest_match '*.js' '<script src="{match}"></script>' %}, the string'*.js'is sent toget_multi_matchaspattern(without surrounding quotes)
Below is the code for the default loader, which is a good starting point:
import fnmatch
from manifest_loader.loaders import LoaderABC
class DefaultLoader(LoaderABC):
@staticmethod
def get_single_match(manifest, key):
return manifest.get(key, key)
@staticmethod
def get_multi_match(manifest, pattern):
matched_files = [file for file in manifest.keys() if
fnmatch.fnmatch(file, pattern)]
return [manifest.get(file) for file in matched_files]
In the above example, get_single_match retrieves the value on the manifest dictionary that matches the key key. If
the key does not exist on the dictionary, it instead returns the key.
get_multi_match uses the recommended fnmatch python standard library to do pattern matching. You could also use
regex in it’s place. Here, it iterates through all the keys in the manifest file, and builds a list of the keys that
match the given pattern. It then returns a list of the values associated with those matched keys.
Activating the custom loader¶
To put the custom loader into use it needs to be registered in your settings.py.
# settings.py
from my_app.utils import MyCustomLoader
MANIFEST_LOADER = {
...
'loader': MyCustomLoader
}
URLs in Manifest File¶
If your manifest file points to full URLs, instead of file names, the full URL will be output instead of pointing to the static file directory in Django.
Example:
{
"main.js": "http://localhost:8080/main.js"
}
{% load manifest %}
<script src="{% manifest 'main.js' %}"></script>
Will output as:
<script src="http://localhost:8080/main.js"></script>
Tests and Code Coverage¶
Run unit tests and verify 100% code coverage with:
git clone https://github.com/shonin/django-manifest-loader.git
cd django-manifest-loader
pip install -e .
# run tests
python runtests.py
# check code coverage
pip install coverage
coverage run --source=manifest_loader/ runtests.py
coverage report