Skip to main content

Use Django's template engine to generate static files at deployment time.

Project description

MIT license PyPI version fury.io PyPI pyversions PyPI status Documentation Status Code Cov Tests Status

django-render-static

django-render-static enables Django’s dynamic templates to be used to generate 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!

Installation

  1. Clone django-render-static from GitHub or install a release off PyPI :

pip install django-render-static
  1. Add ‘render_static’ to your INSTALLED_APPS :

INSTALLED_APPS = [
    'render_static',
]
  1. Add a STATIC_TEMPLATES configuration directive to your settings file:

STATIC_TEMPLATES = {
    'templates' : {
        'path/to/template': {
            'context' { 'variable': 'value' }
        }
}
  1. 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': (
                        'var urls = {\n
                            {% urls_to_js exclude=exclude %}
                        \n};'
                    )
                })
             ],
            '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:

var urls = {
    "simple": function(kwargs={}, args=[]) {
        if (Object.keys(kwargs).length === 0 && args.length === 0)
            return "/simple";
        if (
            Object.keys(kwargs).length === 1 &&
            ['arg1'].every(value => kwargs.hasOwnProperty(value))
        )
            return `/simple/${kwargs["arg1"]}`;
        throw new TypeError("No reversal available for parameters at path: simple");
    },
    "different": function(kwargs={}, args=[]) {
        if (
            Object.keys(kwargs).length === 2 &&
            ['arg1','arg2'].every(value => kwargs.hasOwnProperty(value))
        )
            return `/different/${kwargs["arg1"]}/${kwargs["arg2"]}`;
        throw new TypeError("No reversal available for parameters at path: different");
    }
}

So you can now fetch paths like this:

// /different/143/emma
urls.different({'arg1': 143, 'arg2': 'emma'});

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-render-static-0.1.0.tar.gz (23.5 kB view details)

Uploaded Source

Built Distribution

django_render_static-0.1.0-py3-none-any.whl (24.5 kB view details)

Uploaded Python 3

File details

Details for the file django-render-static-0.1.0.tar.gz.

File metadata

  • Download URL: django-render-static-0.1.0.tar.gz
  • Upload date:
  • Size: 23.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.4 CPython/3.6.10 Darwin/19.6.0

File hashes

Hashes for django-render-static-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c695bd5e44481e6c9a99bac3ada442783cae6be58e0a558dae7409ec765b9ef2
MD5 f144d3da97854bab7898f4c02d13fc1e
BLAKE2b-256 cf376804e68b340283c64da786ad2cdcb288b520658fc32b0856262ce7a3adc1

See more details on using hashes here.

File details

Details for the file django_render_static-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_render_static-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9b577344dab50fc2b4d6caafc15d363618faee517f9cc8311b2fb207486edfd9
MD5 646e866495de98667fe351b488e34f0d
BLAKE2b-256 b0816af0b6f5cf2a5a0fa0d858755c04c4bd474742ac3a24ff2d0251df70e650

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page