Standalone template tag for loading webpack manifest files from multiple Django packages/apps
Project description
Django Multi-Manifest Loader
A simple, standalone template tag for loading webpack manifest files from multiple Django packages/apps. Zero dependencies on unmaintained packages.
Problem
When using webpack with multiple Django packages (like righttowork-check, criminalrecords-check, etc.), each package generates its own manifest.json file with hashed asset filenames for cache busting. However, most manifest loaders only read a single manifest file, making it impossible to reference assets from installed packages.
Solution
django-multi-manifest-loader provides a standalone template tag that:
- Loads the main webpack manifest (from your dashboard/main app)
- Automatically discovers and loads manifest files from all installed Django packages
- Merges them into a single manifest dictionary
- Makes all assets available via the
{% manifest %}template tag - Zero dependencies - doesn't rely on unmaintained packages like
django-manifest-loader
Installation
pip install django-multi-manifest-loader
Or install from source:
cd django-multi-manifest-loader
pip install -e .
Usage
1. Add to INSTALLED_APPS
In your settings.py:
INSTALLED_APPS = [
# ...
'django_multi_manifest_loader',
# ...
]
2. Use in Templates
Now you can use the {% manifest %} tag for assets from any installed package:
{% load manifest %}
{# Main app assets #}
<script src="{% manifest 'js/scripts.bundle.js' %}"></script>
{# Package assets with hashed filenames #}
<script src="{% manifest 'custom/candidate/wizard/multiple-upload.js' %}"></script>
How It Works
The loader searches for manifest files in all installed Django apps using Django's staticfiles finders:
- Main manifest:
manifest.json(from your webpack build) - Package manifests:
*/manifest.json(e.g.,righttoworkcheck/manifest.json)
All manifest entries are merged, so you can reference any asset by its original key, and the loader returns the hashed filename.
Package Manifest Example
In your Django package (e.g., righttowork-check), generate a manifest using webpack:
webpack.config.js:
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
module.exports = {
output: {
path: path.resolve(__dirname, 'static/righttoworkcheck/js/'),
filename: '[name].[contenthash:8].js',
publicPath: 'righttoworkcheck/js/'
},
plugins: [
new WebpackManifestPlugin({
fileName: '../manifest.json',
publicPath: 'righttoworkcheck/js/',
}),
],
};
This generates static/righttoworkcheck/manifest.json:
{
"custom/candidate/wizard/multiple-upload.js": "righttoworkcheck/js/custom/candidate/wizard/multiple-upload.dd215078.js"
}
Configuration
All configuration is optional. Add to your settings.py:
DJANGO_MULTI_MANIFEST_LOADER = {
# Enable/disable manifest caching
# Default: True in production (not DEBUG), False in DEBUG mode
'cache': True,
# Enable debug logging to see which manifests are loaded
# Default: False
'debug': False,
}
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
cache |
bool |
not DEBUG |
Cache merged manifests in memory. Disable in development for hot reloading. |
debug |
bool |
False |
Enable detailed logging of manifest loading process. |
Development
Setup Development Environment
# Clone the repository
cd django-multi-manifest-loader
# Create virtual environment
python3 -m venv .venv
# Activate virtual environment
source .venv/bin/activate # Linux/Mac
# or
.venv\Scripts\activate # Windows
# Install package with dev dependencies
pip install -e ".[dev]"
Running Tests
# Run all tests
pytest
# Run with coverage report
pytest --cov=django_multi_manifest_loader --cov-report=term-missing
# Run specific test file
pytest tests/test_manifest_loader.py -v
Code Quality
# Run all quality checks
flake8 django_multi_manifest_loader/ tests/
black --check django_multi_manifest_loader/ tests/
isort --check-only django_multi_manifest_loader/ tests/
ruff check django_multi_manifest_loader/ tests/
# Auto-format code
black django_multi_manifest_loader/ tests/
isort django_multi_manifest_loader/ tests/
ruff check --fix django_multi_manifest_loader/ tests/
Clear Cache Programmatically
During development, you can clear the manifest cache:
from django_multi_manifest_loader import ManifestLoader
ManifestLoader.clear_cache()
Debug Mode
Enable debug mode to see detailed logging:
# settings.py
DJANGO_MULTI_MANIFEST_LOADER = {
'debug': True,
}
This will log:
- Number of manifest files found
- Path to each manifest being loaded
- Number of entries in each manifest
- Total merged entries
Hot Reloading in Development
By default, caching is disabled in DEBUG mode (cache=not DEBUG). This means:
- Production: Manifests are cached for performance
- Development: Manifests are reloaded on each request for hot reloading
Requirements
- Python >= 3.10
- Django >= 4.0
No other dependencies! This package is completely standalone.
How It Works
The loader uses Django's staticfiles finders to discover manifest files:
- Main manifest: Searches for
manifest.jsonin static directories - Package manifests: Iterates through all
INSTALLED_APPSand checks each for<app_name>/manifest.json - Merging: All found manifests are merged into a single dictionary (later entries override earlier ones)
- Caching: Merged manifest is cached in memory (unless disabled)
Publishing
Automated Publishing to PyPI
The package automatically publishes to PyPI when you push a version tag:
# Update version in __init__.py
# Commit changes
git add django_multi_manifest_loader/__init__.py
git commit -m "Bump version to 0.2.0"
# Create and push tag
git tag v0.2.0
git push origin main --tags
This triggers the GitHub Actions workflow which:
- Runs all tests across Python 3.10-3.12 and Django 4.2-5.1
- Runs all linters (flake8, black, isort, ruff)
- Builds the package
- Publishes to PyPI using trusted publishing (no API tokens needed)
Manual Publishing
# Build package
python -m build
# Check package
twine check dist/*
# Upload to PyPI (requires PyPI credentials)
twine upload dist/*
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_multi_manifest_loader-0.1.2.tar.gz.
File metadata
- Download URL: django_multi_manifest_loader-0.1.2.tar.gz
- Upload date:
- Size: 9.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb7f54138efc5c963e75e75e9b490dd18d72a09f06f8a6dd940674569f0b47ca
|
|
| MD5 |
90f8a4c6696103d419abc92b534bb7e6
|
|
| BLAKE2b-256 |
ebe82d04d82e2cf2b0e6e63da392bdc515370bc51dfd99c4b6378856dd9cb760
|
Provenance
The following attestation bundles were made for django_multi_manifest_loader-0.1.2.tar.gz:
Publisher:
ci.yml on pescheckit/django-multi-manifest-loader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_multi_manifest_loader-0.1.2.tar.gz -
Subject digest:
eb7f54138efc5c963e75e75e9b490dd18d72a09f06f8a6dd940674569f0b47ca - Sigstore transparency entry: 575666560
- Sigstore integration time:
-
Permalink:
pescheckit/django-multi-manifest-loader@adac2468d4779afae5ef4c01ed6faba95a9f311d -
Branch / Tag:
refs/tags/0.1.2 - Owner: https://github.com/pescheckit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@adac2468d4779afae5ef4c01ed6faba95a9f311d -
Trigger Event:
release
-
Statement type:
File details
Details for the file django_multi_manifest_loader-0.1.2-py3-none-any.whl.
File metadata
- Download URL: django_multi_manifest_loader-0.1.2-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1361ac9d9e2963350e6be698c0849116d3260ceea4b645033016c9a175dd3ac4
|
|
| MD5 |
ca48613bfaef9bb7c41b68989ae13537
|
|
| BLAKE2b-256 |
892cba13d7af4a34d3c847bee704e41868550ee16f1be4c055bda1f8853b4e39
|
Provenance
The following attestation bundles were made for django_multi_manifest_loader-0.1.2-py3-none-any.whl:
Publisher:
ci.yml on pescheckit/django-multi-manifest-loader
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
django_multi_manifest_loader-0.1.2-py3-none-any.whl -
Subject digest:
1361ac9d9e2963350e6be698c0849116d3260ceea4b645033016c9a175dd3ac4 - Sigstore transparency entry: 575666566
- Sigstore integration time:
-
Permalink:
pescheckit/django-multi-manifest-loader@adac2468d4779afae5ef4c01ed6faba95a9f311d -
Branch / Tag:
refs/tags/0.1.2 - Owner: https://github.com/pescheckit
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@adac2468d4779afae5ef4c01ed6faba95a9f311d -
Trigger Event:
release
-
Statement type: