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.9 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
        args: [--target-version, "5.2"]  # 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.2 templates/engine.html
1 file reformatted

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.2 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.6.0.tar.gz (40.1 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.6.0-py3-none-win_arm64.whl (985.9 kB view details)

Uploaded Python 3Windows ARM64

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

Uploaded Python 3Windows x86-64

djade-1.6.0-py3-none-win32.whl (963.3 kB view details)

Uploaded Python 3Windows x86

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

Uploaded Python 3musllinux: musl 1.1+ x86-64

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

Uploaded Python 3musllinux: musl 1.1+ ARM64

djade-1.6.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.6.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl (1.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ i686

djade-1.6.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl (1.0 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARMv7l

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

Uploaded Python 3manylinux: glibc 2.17+ ARM64

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

Uploaded Python 3macOS 11.0+ ARM64

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

Uploaded Python 3macOS 10.12+ x86-64

File details

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

File metadata

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

File hashes

Hashes for djade-1.6.0.tar.gz
Algorithm Hash digest
SHA256 a7f173d6949ce248ee538ab85676e3277b4b4ae956c3383f96348355ab8983b7
MD5 c4b0fe8e5e7348c7a2210c389103cb74
BLAKE2b-256 a99c637184b2595d38d9ddcd31076c7ac6b57cd259821481cc8f029616be2b25

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: djade-1.6.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 985.9 kB
  • 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.6.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 c52efaa5d64572ddc4a986d74202195c8574f969877fcfbdbea3a41718334804
MD5 cebe52c28ecf84c6f16d6574f9ed3439
BLAKE2b-256 32a7d3f58feeb1169a41c569b63cb8f23886694f0d72290cbc7eb691b083e0aa

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: djade-1.6.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.6.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 d6111763d133a7a85db0f6f0e59586fdbbd08e6c22238e84de730bb1a21cbab4
MD5 7c58977e171105b3fe103723d4a844a2
BLAKE2b-256 73ff3b4a9ff45c0f8584931031d511721c27f5f4d09852611be2164b42eb74e0

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: djade-1.6.0-py3-none-win32.whl
  • Upload date:
  • Size: 963.3 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.6.0-py3-none-win32.whl
Algorithm Hash digest
SHA256 4555387841d0ef6290ff8221ebea48321262ff1011874debd30010e5deba0ff3
MD5 ff91292533b2cf3c325537b6ed88b568
BLAKE2b-256 ec2e5d942c51cd7c5bb868e942fc3fc9d7cd97617d94a56db0bb40da18d0d0ef

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.6.0-py3-none-musllinux_1_1_x86_64.whl
Algorithm Hash digest
SHA256 a99661ad8b155c3aa62ac2fdb3879df0e5a5bcb1c66f8a142f3964cd2a0bb1cb
MD5 642cbddc6de0f51f64d0fd70c960a20f
BLAKE2b-256 6439e924089cddb183295f7c51ed1587c2f6c956e0efe8b5b594494104c93037

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.6.0-py3-none-musllinux_1_1_aarch64.whl
Algorithm Hash digest
SHA256 4c4c42d86f317742ad1d33f4ca85d4d507530b7cfbfc9b2dc015dda4d06199ad
MD5 3e219b75e59f4bc94c39ef00fa23678e
BLAKE2b-256 ac359324569b8cfa714c1992dba661deb9bf9001c0471986c71c331172c10388

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.6.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 e9ed89688c9baa733cbf4ec08b8cc0102bdd1b539bd0775f5ad5be98e20ab934
MD5 19990f13827577a5c8c2a9a739dc3cfc
BLAKE2b-256 572a3f3053cc7fba84faee5cd8307cb2d548bc26f05e9c4d28bb48b47bf25d0a

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.6.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl
Algorithm Hash digest
SHA256 53511e1d3d55ff408fe11edc7bc982b0af53ab6225870d031804e209ec0515d8
MD5 f79361caa4755db8ac103cf7929e68ad
BLAKE2b-256 79ac7f3fbedf3f229bed3c55fe0e6db4b669d2b5d995c07918739dd4713997f7

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.6.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl
Algorithm Hash digest
SHA256 113a8db4657bd488ecf383c3db0953530012afbccb596302a294c7b629573269
MD5 d0bfb055a14742f379bc179d20f506be
BLAKE2b-256 5c828d829ba658337ee9138f8850d91cab4ea9ccad2a6d23a60fb7c3cbb7ae9b

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.6.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 4dd8a7919f1fa953e332548aeb3b793dea0563fc5e9f89017da6fe7318b603a2
MD5 1eb8bce0558ac1cfd4de800e368bb7a7
BLAKE2b-256 71db2b7d51041c47b65ad0f483379958ac44fb12db7a761a390e0f3423932e6e

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: djade-1.6.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.6.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fe820c5be3d08952ad42ea9ee5475e1c60d32326fae57ee98a4887e99d2d1765
MD5 ab97b6baf2e5ee51eabf742d3f32a5e8
BLAKE2b-256 3778ce1cc79f9311f101ea6721498b1027b7698cd40702af6b50a7842442644d

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for djade-1.6.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 e43eb2227a02599df038ba64b7a0c8599d6cef9d0de978ac635592d58299d477
MD5 5fa192d3df190b373918fb752d490834
BLAKE2b-256 dde6ddfcf10d010a3905232ba2962d2ef00533052913966d06237356871fa48f

See more details on using hashes here.

Provenance

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