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

Uploaded Python 3Windows ARM64

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

Uploaded Python 3Windows x86-64

djade-1.7.0-py3-none-win32.whl (988.1 kB view details)

Uploaded Python 3Windows x86

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

Uploaded Python 3musllinux: musl 1.1+ x86-64

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

Uploaded Python 3musllinux: musl 1.1+ ARM64

djade-1.7.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.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (1.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ i686

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

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

djade-1.7.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.7.0.tar.gz.

File metadata

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

File hashes

Hashes for djade-1.7.0.tar.gz
Algorithm Hash digest
SHA256 b49e7ad42050ecac10ae990a6adbecec08c62b0a32a33de748d63d948bced815
MD5 697ada13ff76bc81440b37f41bc0f1f0
BLAKE2b-256 d53105baa6b0419c6cd13e4ecae275aadfb6d5c0b332f1b06d4fccb4cb4a2b29

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: djade-1.7.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.7.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 fef26be22c5b3c15e6b8be3888ae0672aab5067d219cf2be145af22860757c08
MD5 713845ff6b4098bf717b23c4c39be56a
BLAKE2b-256 2c51438fcae17c2afa62966f0fbda3799f3bada7110d92cc3c58ebc47b636925

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: djade-1.7.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.7.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 a1d41819a0409c74e0e521e856799cbce38c50a1bd5b020fa209a40f9441b499
MD5 c93810ac04410188ebdded50eeaf5df9
BLAKE2b-256 f9ddfea876ed43f13182a6381c56dbe8daf4ed4d745228292c38ea44e85ea56d

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.7.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.7.0-py3-none-win32.whl.

File metadata

  • Download URL: djade-1.7.0-py3-none-win32.whl
  • Upload date:
  • Size: 988.1 kB
  • Tags: Python 3, Windows x86
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for djade-1.7.0-py3-none-win32.whl
Algorithm Hash digest
SHA256 20308b03c51bd2551137f5852afb663ac5f86015321cc4f45363427f7dbd9534
MD5 2f9f72db971f54bc571a9a653999c450
BLAKE2b-256 0c548b2fc833d1fdeb08d9e87a1db7dd8d4b64854b9d62c7867b69519c357f21

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.7.0-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 51221cff697e1eaa709e375ecac331366ec68cd90567de36f4bd3daca94e8327
MD5 e4e54ea51f6eb0a14483cb103c11b516
BLAKE2b-256 d0a1462b4e004c5fc9ce9d4f93968e8ee5ba646c033f95e05fc70d8864ac3cb8

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.7.0-py3-none-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 7fbdfece645f5816adae816eed847db1905d1e14cba3da5384706adce1eefb2a
MD5 a11e9f36cfb2671da0079d461d30ab63
BLAKE2b-256 dda273839c8d4f9e96ed3f4a4e6e51cc2934fdbc1f1f4ff8be1effbdb7574fe5

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 9596896b44e25fbd897e0e8d134a108184f56c32feff8607028daa2315506f47
MD5 afe81de80b8dc8d8822c2b1b35801230
BLAKE2b-256 6a88a5a79f2e57e13c0403a238173744d3eb08f03616f0e399a6fe88a806bf66

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.7.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.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl.

File metadata

File hashes

Hashes for djade-1.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 6aa4659a2c3c172cf0ed35d19cb2d396248e6889b47b4ae52263be1d89f0a532
MD5 4bfab84bbfe9a5773069a60399687782
BLAKE2b-256 0d2d30f9ce233e02e9e29793b8eb2784a09d5d18b8aa6bbb53374403cee39ac8

See more details on using hashes here.

Provenance

The following attestation bundles were made for djade-1.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.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.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl.

File metadata

File hashes

Hashes for djade-1.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 db11d4563b73c3eacd2433005e9467d67c3a58c61ce6b5d821b89b124d1dd168
MD5 03a97dd0d13765c56c526ace79c0a7b6
BLAKE2b-256 e9aaba674b4a78be552f9bba496369f0a436b0eebc0bfc7c41bd250776428967

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 0102aaf6f1a259f2ca78839c796b130fc53868965b01fb0b8d5768c5fe142b99
MD5 3136101d650cc1470b2c1a46a7cb4399
BLAKE2b-256 f55d781d7204973cd12138805d4a6b67ec7666771b66709242f6b7b6834f862b

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: djade-1.7.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.7.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9676b72b9e9e494d977f887cda825e333e699ae7184384795d5a9e2e5d2c7f69
MD5 c727e7c2a0e361f22440cf83d70fc6bf
BLAKE2b-256 bb1f8ca54f7d4ab2c26095f938cedb13d2508032d9eadcfd07757a46a02cc38a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.7.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 084f505338862542343d4cabbd52a8e58a8b05cc1a0eb37d78824073485d4c8d
MD5 d8aa542b71ec3893d1868bf0abdbce86
BLAKE2b-256 e941d25b88a4ff05a495aaf992793eae116b867e6a4ebda64701f737f22abf18

See more details on using hashes here.

Provenance

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