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 #}
  • 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 %}

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.8.0.tar.gz (39.9 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.8.0-py3-none-win_arm64.whl (1.0 MB view details)

Uploaded Python 3Windows ARM64

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

Uploaded Python 3Windows x86-64

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

Uploaded Python 3musllinux: musl 1.1+ x86-64

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

Uploaded Python 3musllinux: musl 1.1+ ARM64

djade-1.8.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.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (1.1 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

djade-1.8.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.8.0.tar.gz.

File metadata

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

File hashes

Hashes for djade-1.8.0.tar.gz
Algorithm Hash digest
SHA256 a0f449a4d6d92da475a122ca2008598882e27c70c1b233f69d90fb0a37458c23
MD5 9acafd97d995516851fe02ae552bd1a6
BLAKE2b-256 f4be6bfee7af62d1775d470e2d2b42baa386f14b5e3bb434b4fcfa5aab7230b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: djade-1.8.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.8.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 467d7a446199c96291906fe4097110f712ef75d6cb64f3c51e04a2943a0c491e
MD5 bce45db60547ca7a297a3fb90677e10c
BLAKE2b-256 9e475e09766e8e32e18d5dc28a7e08fba5fbdac0979fe5a3b198e764e6c3b2a3

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: djade-1.8.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.8.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 d61e2fbc3e7188db5a7adb487ffe1670417f4db5437850fa4a775b065c1a3cd7
MD5 f126a27477050ce6227e6f07f55619a9
BLAKE2b-256 84685f4064efa1537f44477fbc2693e083a6aec25e00550ffe224d3cc037ec56

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-musllinux_1_1_x86_64.whl.

File metadata

File hashes

Hashes for djade-1.8.0-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 297b994a902a3a32563401bb654186ffa8268d610ea29fa213925aaa9e3a24fc
MD5 a8fc3f5b6a42b1d009274ee42563cc1b
BLAKE2b-256 aee67a85b705c822bd33bd9c26aa4e8b0c91dfe596c564e4c4bfbecac3200261

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-musllinux_1_1_aarch64.whl.

File metadata

File hashes

Hashes for djade-1.8.0-py3-none-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 90e18e263d2752dc95b09c722e7498316815a07fd8a82c141e820ea4b20f2053
MD5 0ec5f64a1709e834049256dd796ad04f
BLAKE2b-256 aee025b841ee573db45996b423317815fa8fd81e91a9279588228343963efff6

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for djade-1.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a8d2957ab2c01a867b6ed3cd16f69cab4e9e66677644024171b23beb4bdeb387
MD5 50a825d852a90e865bf842dce1933d01
BLAKE2b-256 1b75cd076f2878de1a780d76638fd8e8deb00a4dd6a3232d6a015e36b793fe91

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for djade-1.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 216c5d761092003c0983141e375f6f2353b048ddadbf00f27fd703369346bd7c
MD5 cbd9bb8aba3ac48341948de8659d03dc
BLAKE2b-256 f7329cbe9f7076a21b9331b9b064576c3c184c098dd90b7f1c996e16567e1b3f

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for djade-1.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 c7590f0b4a43fc9448570a6880f9f1c221022ddcb676f26b0e215d4b52409fb4
MD5 8133ad9ef25c81ea8934461398230927
BLAKE2b-256 8f742ddb5ff6abeaa7019a6f89d7ea1fd27172e6aeca0d8e6554aa84de7745e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: djade-1.8.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.8.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0044536977d41770dab6746d815f00a6ccfc1df542934c8ae36bbefab1616cc9
MD5 fedf4cca8a0f406f56fb897afe756ed2
BLAKE2b-256 9ee9a2f4762c60566d85dcf9e8115fec5f7c91cb5d34b22632430e73b91e171f

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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.8.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for djade-1.8.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 4f5fcd2ff123d2c2429d372e7b5eb9ebce5dd7244322ba58061d774ecf1ddef4
MD5 639b3e7dab165c94344fa40bfc62e736
BLAKE2b-256 98fc00999e55a327692a3294798773daeb78959dfaacc2fae3c11fb3f7d68008

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.8.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