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 is 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.10 to 3.14 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

Djade attempts to parse your current Django version from pyproject.toml. If this doesn’t work for you, specify your target version with the --target-version option:

 -   id: djade
+    args: [--target-version, "5.2"]   # Replace with Django version

The separate repository (djade-pre-commit) 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 templates/engine.html
1 file reformatted

Djade can also upgrade some old template syntax, up to a target Django version, which may be specified with the --target-version option. When --target-version is not specified, Djade attempts to detect the target version from a pyproject.toml in the current directory. If found, it attempts to parse your current minimum-supported Django version from project.dependencies, supporting formats like django>=5.2,<6.0. When available, it reports:

$ django-upgrade example.py
Detected Django version from pyproject.toml: 6.0
1 file reformatted

If this doesn’t work, no upgrade fixers are applied, unless you pass --target-version with a Django version formatted as <major>.<minor>:

$ djade --target-version 6.0 templates/engine.html
1 file reformatted

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 -0r djade

…or PowerShell’s ForEach-Object:

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

The filename - makes Djade read from standard input and write to standard output. In this case, Djade always exits with code 0, even if changes were made.

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 #}
  • Label {% endpartialdef %} tags that aren’t on the same line as their opening {% partialdef %} tag:

    {% partialdef whistle %}
    ...
    -{% endpartialdef %}
    +{% endpartialdef whistle %}
  • No labels in {% endblock %} tags on the same line as their opening {% block %} tag:

    -{% block funnel %}...{% endblock funnel %}
    +{% block funnel %}...{% endblock %}
  • No labels in {% endpartialdef %} tags on the same line as their opening {% partialdef %} tag:

    -{% partialdef whistle %}...{% endpartialdef whistle %}
    +{% partialdef whistle %}...{% endpartialdef %}
  • 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 %}

Django 1.3+: legacy variable assignment syntax

The minimum target Django version is 2.1, so this fixer is always active.

Django 1.3 added support for = to assign variables in {% with %} and {% blocktranslate %} tags. Prior to this, they only supported the legacy syntax using the as keyword, which Django still supports.

Djade rewrites the older as syntax to the newer = one:

-{% with engines.count as total %}
+{% with total=engines.count %}
     ...
 {% endwith %}

-{% blocktranslate with engine.colour as colour %}
+{% blocktranslate with colour=engine.colour %}
     ...
 {% endblocktranslate %}

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.9.0.tar.gz (42.0 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

djade-1.9.0-py3-none-win_arm64.whl (1.0 MB view details)

Uploaded Python 3Windows ARM64

djade-1.9.0-py3-none-win_amd64.whl (1.1 MB view details)

Uploaded Python 3Windows x86-64

djade-1.9.0-py3-none-musllinux_1_1_x86_64.whl (1.3 MB view details)

Uploaded Python 3musllinux: musl 1.1+ x86-64

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

Uploaded Python 3musllinux: musl 1.1+ ARM64

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

Uploaded Python 3manylinux: glibc 2.17+ x86-64

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

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

djade-1.9.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

djade-1.9.0-py3-none-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

djade-1.9.0-py3-none-macosx_10_12_x86_64.whl (1.2 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

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

File metadata

  • Download URL: djade-1.9.0.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for djade-1.9.0.tar.gz
Algorithm Hash digest
SHA256 e07dcec03982af3f12e46e42661c83ba6835edbde3597e0385ecfe7385527721
MD5 d96691ffe97ab4c144c631d63d5c7944
BLAKE2b-256 992e655cc12eefa761d54b9cb956b8650f83675fd144fda641b03d4172d2e0c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0.tar.gz:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: djade-1.9.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 1.0 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for djade-1.9.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 b90633a53bb996e0fffd9bd26ed995a78b15f368aea77348e35e67151de4fd13
MD5 354c664f9706e70fe3a4bb9fb09670ac
BLAKE2b-256 4314e39757938c1387c29b27e9362f3b567a8f6b24bd223137a11253b0c315e7

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-win_arm64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: djade-1.9.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for djade-1.9.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 bb2b62e22971173dae63bb2d18b24fe85bf3470ca1aabf1b8320a578832d64a2
MD5 82a3fc2f6fa779dcbb9214bdc43141be
BLAKE2b-256 70ddbbbf681b4918fd178bd6586b28146af55e8f0c833e6ce26f255fe4f0271a

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-win_amd64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

File hashes

Hashes for djade-1.9.0-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 1981f77ef3c8b73860e492918ce235e46ab4e62a63c8101dd379e204c8a162de
MD5 667dc912f7a300d05b7233bc7c716a6d
BLAKE2b-256 faea190854396549d3741b70fd5f828ca0cfeee203e7a6219500cc9bc97bab76

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-musllinux_1_1_x86_64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

File hashes

Hashes for djade-1.9.0-py3-none-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 183b828ffcedb0122bcf0b5eaa008bb288c344a80946c3f372d583f3944c1394
MD5 23c7134259e2a36be26aecc60473184d
BLAKE2b-256 d3226713dd41f6c6615bf6f11f552286f2ff0e56e4eb0050f6223d1932b38678

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-musllinux_1_1_aarch64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

File hashes

Hashes for djade-1.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9b90e709d21c3f953b52fc5a021b8ef69b0790f23aa308923992af1fc3c2353f
MD5 3bf7d5704e3ce44577ce4875d0bc2ebf
BLAKE2b-256 019a59396b03db75dd14f74402adb7348362863fde05313f643542dc24ae665e

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

File hashes

Hashes for djade-1.9.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 d9d828aaa871c02655d0a6b2d9fd2a677cd4b16bd101015728dd5db418b8225b
MD5 7b98b9bfc426a8f0a627dc6d70e05054
BLAKE2b-256 908dcb656b034477b734adefa69c7ada69d17bde4a7bf5a69e797f53ac59ecc3

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

File hashes

Hashes for djade-1.9.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 fbfc70ad912b54329363de7a5b62afd6bf4b92a49c12e2a155be1138cef01424
MD5 3a08cb7906de2bb6ee38751abafe2906
BLAKE2b-256 b595e6f43a63e9c6297e3117d5e8415c78c64f4403cace455641b6eb6590d7e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: djade-1.9.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for djade-1.9.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8da28ee6ac2e163283c1f19965f04cb4ca1e4e9fd9edc4c1f4cf183cab98384e
MD5 20530f705c98a7f9fc1107d85aa12239
BLAKE2b-256 8f022098990d681265e84e8d0d2b4548279dcaae07195d217f71e799f4006025

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-macosx_11_0_arm64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

File hashes

Hashes for djade-1.9.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 9523c5eebf67bdf4037cbaa3c79fbb453ee883c370e772f2dbb767c753971ac7
MD5 1eb136bf7817b5fa4d153ee4d6a7becc
BLAKE2b-256 751c40f332f13fc63495677aca02a22a74e5dd596f85d762fd34dcad7177a878

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.9.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: main.yml on adamchainz/djade

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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