Use Django's template engine to render static files at deployment time. Extend Django's url reverse mechanism to JavaScript.
Project description
django-render-static
Use Django’s dynamic templates to render static files. That is, files that are collected during the collectstatic routine and likely served above Django on the stack. Static templates should be rendered preceding any run of collectstatic.
For example, a frequently occurring pattern that violates the DRY principle is the presence of defines, or enum like structures in server side Python code that are simply replicated in client side JavaScript. Single-sourcing these structures by generating client side code from the server side code maintains DRYness.
Have you ever wished you could replicate Django’s reverse function in a JavaScript library for your site? Now you can with the urls_to_js template tag included with django-render-static.
You can report bugs and discuss features on the issues page.
Contributions are encouraged! Especially additional template tags and filters!
Full documentation at read the docs.
Installation
pip install django-render-static
Add ‘render_static’ to your INSTALLED_APPS :
INSTALLED_APPS = [
'render_static',
]
Add a STATIC_TEMPLATES configuration directive to your settings file:
STATIC_TEMPLATES = {
'templates' : {
'path/to/template': {
'context' { 'variable': 'value' }
}
}
Run render_static preceding every run of collectstatic :
$> manage.py render_static
$> manage.py collectstatic
Usage
Generating Javascript Defines
You have an app with a model with a character field that has several valid choices defined in an enumeration type way, and you’d like to export those defines to JavaScript. You’d like to include a template for other’s using your app to use to generate a defines.js file. Say your app structure looks like this:
. └── my_app ├── __init__.py ├── apps.py ├── defines.py ├── models.py ├── static_templates │ └── my_app │ └── defines.js └── urls.py
Your defines/model classes might look like this:
class Defines:
DEFINE1 = 'D1'
DEFINE2 = 'D2'
DEFINE3 = 'D3'
DEFINES = (
(DEFINE1, 'Define 1'),
(DEFINE2, 'Define 2'),
(DEFINE3, 'Define 3')
)
class MyModel(Defines, models.Model):
define_field = models.CharField(choices=Defines.DEFINES, max_length=2)
And your defines.js template might look like this:
var defines = { {{ "my_app.defines.Defines"|split|classes_to_js }} };
If someone wanted to use your defines template to generate a JavaScript version of your Python class their settings file might look like this:
STATIC_TEMPLATES = {
'templates': {
'my_app/defines.js': {}
}
}
And then of course they would call render_static before collectstatic:
$> ./manage.py render_static
$> ./manage.py collectstatic
This would create the following file:
. └── my_app └── static └── my_app └── defines.js
Which would look like this:
var defines = {
Defines: {
DEFINE1: 'D1'
DEFINE2: 'D2'
DEFINE3: 'D3'
DEFINES: [
['D1', 'Define 1'],
['D2', 'Define 2'],
['D3', 'Define 3']
]
}
};
URL reverse functions
You’d like to be able to call something like reverse on path names from your client JavaScript code the same way you do from Python Django code. You don’t want to expose your admin paths though.
Your settings file might look like:
from pathlib import Path
BASE_DIR = Path(__file__).parent
STATICFILES_DIRS = [
BASE_DIR / 'more_static'
]
STATIC_TEMPLATES = {
'ENGINES': [{
'BACKEND': 'render_static.backends.StaticDjangoTemplates',
'OPTIONS': {
'loaders': [
('render_static.loaders.StaticLocMemLoader', {
'urls.js': (
'{% urls_to_js visitor="render_static.ClassURLWriter" '
'exclude=exclude %}'
)
})
],
'builtins': ['render_static.templatetags.render_static']
},
}],
'templates': {
'urls.js': {
'dest': BASE_DIR / 'more_static' / 'urls.js',
'context': {
'exclude': ['admin']
}
}
}
}
Then call render_static before collectstatic:
$> ./manage.py render_static $> ./manage.py collectstatic
If your root urls.py looks like this:
from django.contrib import admin
from django.urls import include, path
from .views import MyView
urlpatterns = [
path('admin/', admin.site.urls),
path('simple', MyView.as_view(), name='simple'),
path('simple/<int:arg1>', MyView.as_view(), name='simple'),
path('different/<int:arg1>/<str:arg2>', MyView.as_view(), name='different'),
]
Then urls.js will look like this:
class URLResolver {
match(kwargs, args, expected) {
if (Array.isArray(expected)) {
return Object.keys(kwargs).length === expected.length &&
expected.every(value => kwargs.hasOwnProperty(value));
} else if (expected) {
return args.length === expected;
} else {
return Object.keys(kwargs).length === 0 && args.length === 0;
}
}
reverse(qname, kwargs={}, args=[]) {
let url = this.urls;
for (const ns of qname.split(':')) {
if (ns && url) { url = url.hasOwnProperty(ns) ? url[ns] : null; }
}
if (url) {
let pth = url(kwargs, args);
if (typeof pth === "string") { return pth; }
}
throw new TypeError(`No reversal available for parameters at path: ${qname}`);
}
urls = {
"simple": (kwargs={}, args=[]) => {
if (this.match(kwargs, args)) { return "/simple/"; }
if (this.match(kwargs, args, ['arg1'])) { return `/simple/${kwargs["arg1"]}`; }
},
"different": (kwargs={}, args=[]) => {
if (this.match(kwargs, args, ['arg1','arg2'])) {
return `/different/${kwargs["arg1"]}/${kwargs["arg2"]}`;
}
},
}
};
So you can now fetch paths like this:
// /different/143/emma
const urls = new URLResolver();
urls.reverse('different', {'arg1': 143, 'arg2': 'emma'});
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
File details
Details for the file django-render-static-1.0.0.tar.gz
.
File metadata
- Download URL: django-render-static-1.0.0.tar.gz
- Upload date:
- Size: 29.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.6 CPython/3.6.10 Darwin/19.6.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e175cdf94dfd3ab4fc3acb0c6292d778c1bae415ea589da660b8bb455d188caa |
|
MD5 | d967351a2328c028ec19d9f112c35307 |
|
BLAKE2b-256 | 294fd02ce25b1f10a23a5c5ccb8a87261c7906fcd24977b1d59ada31f6089185 |
File details
Details for the file django_render_static-1.0.0-py3-none-any.whl
.
File metadata
- Download URL: django_render_static-1.0.0-py3-none-any.whl
- Upload date:
- Size: 31.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.6 CPython/3.6.10 Darwin/19.6.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 87beb00d44de7f81a0c8b37de36533320ef205d0b68933408692420963843b44 |
|
MD5 | e694dba6752b19ee36d46119f9d597cf |
|
BLAKE2b-256 | e63bf1a7465eb0fbb60260cca9135080148fef37a9fe6815192294162109fa4b |