Skip to main content

A Django template formatter.

Project description

https://img.shields.io/github/actions/workflow/status/adamchainz/djade/main.yml.svg?branch=main&style=for-the-badge https://img.shields.io/pypi/v/djade.svg?style=for-the-badge pre-commit
You can have any colour you like, as long as it’s jade.

A Django template formatter.

You can have any colour you like, as long as it’s [d]jade.

Djade formats Django template syntax with a style based on the template style guide in Django’s documentation. It does not format HTML or other templated languages.

Djade is fast because it iss built in Rust: benchmarked taking 20ms to format 377 templates.

Read more in the introductory post, or below.


Improve your Django and Git skills with my books.


Installation

Use pip:

python -m pip install djade

Python 3.8 to 3.13 supported.

pre-commit hook

You can also install Djade as a pre-commit hook.

First, add the following to the repos section of your .pre-commit-config.yaml file (docs):

-   repo: https://github.com/adamchainz/djade-pre-commit
    rev: ""  # Replace with the latest tag on GitHub
    hooks:
    -   id: djade
        args: [--target-version, "5.1"]  # Replace with Django version

The separate repository enables installation without compiling the Rust code.

The default configuration uses pre-commit’s files option to pick up all text files in directories called templates (source). You may wish to override this if you have templates in different directories by adding files to the hook configuration in your .pre-commit-config.yaml file.

Second, format your entire project:

pre-commit run djade --all-files

Check these changes for any potential Djade bugs and commit them. Try git diff --ignore-all-space to check non-whitespace changes.

Third, consider adding the previous commit SHA to a .git-blame-ignore-revs file. This will prevent the initial formatting commit from showing up in git blame.

Keep the hook installed to continue formatting your templates. pre-commit’s autoupdate command will upgrade Djade so you can take advantage of future features.

Usage

djade is a command line tool that rewrites files in place. Pass a list of template files to format them:

$ djade --target-version 5.1 templates/**/*.html
Rewriting templates/locomotives/steam_engine.html
Rewriting templates/locomotives/diesel.html

Djade can also upgrade some old template syntax. Add the --target-version option with your Django version as <major>.<minor> to enable applicable fixers:

$ djade --target-version 5.1 templates/**/*.html
Rewriting templates/locomotives/steam_engine.html

Djade does not have any ability to recurse through directories. Use the pre-commit integration, globbing, or another technique to apply it to many files. For example, with git ls-files | xargs:

git ls-files -z -- '*.html' | xargs -0 djade

…or PowerShell’s ForEach-Object:

git ls-files -- '*.html' | %{djade $_}

Options

--target-version

Optional: the version of Django to target, in the format <major>.<minor>. If provided, Djade enables its fixers for versions up to and including the target version. See the list of available versions with djade --help.

--check

Avoid writing any formatted files back. Instead, exit with a non-zero status code if any files would have been modified, and zero otherwise.

Formatting

Djade aims to format Django template syntax in a consistent, clean way. It wants to be like Black: opinionated and free of configuration. Djade’s style is based on the rules listed in the Django contribution style guide’s template style section, plus some more.

Djade does not aim to format the host language of templates (HTML, etc.). That is a much broader scope and hard to do without semantic changes. For example, whitespace is significant in some HTML contexts, such as in <pre> tags, so even adjusting indentation can affect the meaning.

Below are the rules that Djade implements.

Rules from the Django style guide:

  • Single spaces at the start and end of variables and tags:

    -{{train}}
    +{{ train }}
    
    -{%  blow whistle  %}
    +{% blow whistle %}
  • Label {% endblock %} tags that aren’t on the same line as their opening {% block %} tag:

     {% block funnel %}
     ...
    -{% endblock %}
    +{% endblock funnel %}
  • Sort libraries in {% load %} tags:

    -{% load coal boiler %}
    +{% load boiler coal %}
  • Inside variables, no spaces around filters:

    -{{ fire | stoke }}
    +{{ fire|stoke }}
  • Inside tags, single spaces between tokens:

    -{% if  locomotive  ==  'steam engine'  %}
    +{% if locomotive == 'steam engine' %}
  • Unindent top-level {% block %} and {% endblock %} tags when {% extends %} is used:

    -  {% extends 'engine.html' %}
    +{% extends 'engine.html' %}
    
    -  {% block boiler %}
    +{% block boiler %}
       ...
    -  {% endblock boiler %}
    +{% endblock boiler %}

Extra rules:

  • No leading empty lines:

    -
     {% extends 'engine.html' %}
     ...
  • No trailing empty lines:

     ...
     {% endblock wheels %}
    -
    -
  • Single spaces at the start and end of comments:

    -{#choo choo#}
    +{# choo choo #}
  • No labels in {% endblock %} tags on the same line as their opening {% block %} tag:

    -{% block funnel %}...{% endblock funnel %}
    +{% block funnel %}...{% endblock %}
  • Merge consecutive {% load %} tags:

    -{% load boiler %}
    -
    -{% load coal %}
    +{% load boiler coal %}
  • Sort loaded items in {% load ... from .. %} tags:

-{% load steam heat from boiler %}
+{% load heat steam from boiler %}
  • Unindent {% extends %} tags:

    -  {% extends 'engine.html' %}
    +{% extends 'engine.html' %}
  • Exactly one blank line between top-level {% block %} and {% endblock %} tags when {% extends %} is used:

 {% extends 'engine.html' %}

-
 {% block funnel %}
   ...
 {% endblock funnel %}
+
 {% block boiler %}
   ...
 {% endblock boiler %}

Fixers

Djade applies the below fixes based on the target Django version from --target-version.

Django 4.2+: length_is -> length

From the release note:

The length_is template filter is deprecated in favor of length and the == operator within an {% if %} tag.

Djade updates usage of the deprecated filter within if tags, without other conditions, appropriately:

-{% if engines|length_is:1 %}
+{% if engines|length == 1 %}

Django 4.1+: empty ID json_script fixer

From the release note:

The HTML <script> element id attribute is no longer required when wrapping the json_script template filter.

Djade removes the argument where json_script is passed an empty string, to avoid emitting id="":

-{% tracks|json_script:"" %}
+{% tracks|json_script %}

Django 3.1+: trans -> translate, blocktrans / endblocktrans -> blocktranslate / endblocktranslate

From the release note:

The renamed translate and blocktranslate template tags are introduced for internationalization in template code. The older trans and blocktrans template tags aliases continue to work, and will be retained for the foreseeable future.

Djade updates the deprecated tags appropriately:

-{% load blocktrans trans from i18n %}
+{% load blocktranslate translate from i18n %}

-{% trans "Engine colours" %}
+{% translate "Engine colours" %}

-{% blocktrans with colour=engine.colour %}
+{% blocktranslate with colour=engine.colour %}
 This engine is {{ colour }}.
-{% endblocktrans %}
+{% endblocktranslate %}

Django 3.1+: ifequal and ifnotequal -> if

From the release note:

The {% ifequal %} and {% ifnotequal %} template tags are deprecated in favor of {% if %}.

Djade updates the deprecated tags appropriately:

-{% ifequal engine.colour 'blue' %}
+{% if engine.colour == 'blue' %}
 Thomas!
-{% endifequal %}
+{% endif %}

-{% ifnotequal engine.colour 'blue' %}
+{% if engine.colour != 'blue' %}
 Not Thomas.
-{% endifnotequal %}
+{% endif %}

Django 2.1+: admin_static and staticfiles -> static

From the release note:

{% load staticfiles %} and {% load admin_static %} are deprecated in favor of {% load static %}, which works the same.

Djade updates {% load %} tags appropriately:

-{% load staticfiles %}
+{% load static %}

-{% load admin_static %}
+{% load static %}

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

djade-1.2.0.tar.gz (33.3 kB view details)

Uploaded Source

Built Distributions

djade-1.2.0-py3-none-win_arm64.whl (828.8 kB view details)

Uploaded Python 3 Windows ARM64

djade-1.2.0-py3-none-win_amd64.whl (906.0 kB view details)

Uploaded Python 3 Windows x86-64

djade-1.2.0-py3-none-win32.whl (821.0 kB view details)

Uploaded Python 3 Windows x86

djade-1.2.0-py3-none-musllinux_1_1_x86_64.whl (1.2 MB view details)

Uploaded Python 3 musllinux: musl 1.1+ x86-64

djade-1.2.0-py3-none-musllinux_1_1_aarch64.whl (1.1 MB view details)

Uploaded Python 3 musllinux: musl 1.1+ ARM64

djade-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ x86-64

djade-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (1.2 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ i686

djade-1.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (1.1 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ ARMv7l

djade-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.1 MB view details)

Uploaded Python 3 manylinux: glibc 2.17+ ARM64

djade-1.2.0-py3-none-macosx_11_0_arm64.whl (1.0 MB view details)

Uploaded Python 3 macOS 11.0+ ARM64

djade-1.2.0-py3-none-macosx_10_12_x86_64.whl (1.1 MB view details)

Uploaded Python 3 macOS 10.12+ x86-64

File details

Details for the file djade-1.2.0.tar.gz.

File metadata

  • Download URL: djade-1.2.0.tar.gz
  • Upload date:
  • Size: 33.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for djade-1.2.0.tar.gz
Algorithm Hash digest
SHA256 f8b2d0d38d9bb483fc2d69598c53c663a20e7993961c67be279466936b5e785d
MD5 6d84ab9e8bdfbc188c4de015c5bd1a7e
BLAKE2b-256 8af42bcef5a3cb506588c712fc5cdea065d3fcc4453c6456cb15cc7a212ec473

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: djade-1.2.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 828.8 kB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for djade-1.2.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 5d2825c23eb4dbc4fb71b72781444f47119c1021a126458575218cdddc1fa153
MD5 a3bada6a73cbaa64226236150a0f0d0f
BLAKE2b-256 f3715c1b9ff9ac6c89aeb4da3c426f16cb85aaeb34c2a269e6af5ec0440bb11c

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: djade-1.2.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 906.0 kB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for djade-1.2.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 22284fae0d522c91e45c3a1f9f960e7974efd64f4df85e76f670c32efbc26a20
MD5 a86dbdc05d1e36870c47e1811c577509
BLAKE2b-256 6cfa72011833d53c5170efcd1d7131006a23896512e2a8b26fd9102776936bfa

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-win32.whl.

File metadata

  • Download URL: djade-1.2.0-py3-none-win32.whl
  • Upload date:
  • Size: 821.0 kB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for djade-1.2.0-py3-none-win32.whl
Algorithm Hash digest
SHA256 515bc49b4a53d84390d977ba3a299e032cbf526ab6cb27efa5371663870c50fe
MD5 5f21d9358733337b3d21105b8d5fd5d4
BLAKE2b-256 2f5dc35d312a8d29cb627da8d01eb9eefdcbed681b141c6d1472dd5071505098

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 da76c748cf30a81357ef4a2cb28cbc3a3bf956e65eb7e2f854acf1080135c250
MD5 806e397e84a143dfafe98cf40adac035
BLAKE2b-256 d04bdbfecb0448068d256257d06760414733acb62697039816c1efdf712ce575

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 b29a576b48930354385c09673905f52a99c4e3cb5016442c1b174cae848f1784
MD5 fd4d0a519a27263fc95d67c6ae99c184
BLAKE2b-256 a1868b0c2c650e0fa25c70a128ce7d68491d375b53e6735b6d39b823ee002879

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 988e475196d07e5cbcc14f39cc3b12bb9d40ffdb241aaaec330d6ffae2348afc
MD5 3f680d309917f5d35a03262656f6c3ba
BLAKE2b-256 330a35922888642d7af465dfd0622323091226038cc54de5bc455671b0c15ab7

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 7490fda7c48acfd000aa3580509225303d42ace19dcf8ec3b04ec8d8c816d838
MD5 4742deb00d07ee1f4a4d8ce206dbb171
BLAKE2b-256 a57d515a27a3298984a46dc8894d946e3769d48272421e3fce2bdbed5c00aea5

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 1633516b2083ef18c627149cfa5f1964c9eaced9ce1a8618fab348f364ae8698
MD5 1c5b838718e8b4d498940edd4305715a
BLAKE2b-256 bd43f5487a3ae730948b509b8b42d66c8dbbedbca018eb6defdf9bf4a2930c0f

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0468935ad3c6155fb5a121fe50cfdb92a367751b73c68176234d2980add9b66d
MD5 55191f045d73a09da70f20dfc33dd9fc
BLAKE2b-256 427304b844aacba02e0ffa403fb669ee0508d0096d3ab89bda7600438b0dbbae

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dac153edc06b490937afedfe5ea5bb357f56b45744cf469d18fed46cc20fabbe
MD5 9d2333450dfe2dd809b2daaaebcc5629
BLAKE2b-256 160b0905ce651e9e2e10fa6f1e6c424bdb34c2ab25f806d4c0894acc1ce96b9f

See more details on using hashes here.

File details

Details for the file djade-1.2.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for djade-1.2.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 a8e381621a12175e1cf90f0052020d9ec623cbe85920e9c77d0b545a55d1e741
MD5 bb609df0f2d261b4ead98c3e54e0a96b
BLAKE2b-256 2b7c53a73ff00cf8106339ae50d07f93ad8fdd9bd7c8d7879fd30396ae30ccd0

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