Django Template Style Guide - Ticket 14831

Ticket 14831 has the following details:

It would be nice to have a standard template style that should be followed. For example, I like to indent my Django templates by two additional spaces every time I enter a new HTML or template block. The Django core templates vary greatly in regards to style and indentation. Much of the time template readability is sacrificed in favour of attempting to preserve the “appearance” of the generated HTML code.

Regardless of what is decided, it would be great to have at least some guidelines for templates added to ​http://docs.djangoproject.com/en/dev/internals/contributing/#coding-style

The guidance on moving the ticket forward from @nessita was:

  1. An overview of the various styles found in the current templates,
  2. A draft patch based on whatever the most common/best practice seems to be,
  3. A thread on the Django Forum to let folks debate the options.

I’ve not done anything (yet) for point (2) above, but I have reviewed the various styles that seem to be in place (1) and am now posting here to let folks debate the options (3)

My findings are (and can be found in more detail in comments 10 through 17:

  • The usage of {{ is generally followed by a single space (inline javascript seems to be the exception)
  • The usage of {% is always followed by a single space (the one exception I was able to find was related to a jinja2 whitespace control in ./forms/jinja2/django/forms/widgets/multiwidget.html
  • {% extends %}is always at the top of html files
  • {% load %} is nearly always at the top. There are two exceptions.

{% block %}

The following ‘standards’ are used:
- the <link ...> tends to be on a single line, see for example /django/contrib/admin/templates/admin/base.html ​Line 6
- Simple logic for html element classes tends to be on a single line, see for example ./docs/_theme/djangodocs/layout.html ​Line 80
- Single elements can are on a single line, see for example ./django/contrib/admin/templates/admin/base.html ​Line 102

There are two files which may fall outside of the standard:

  • ./django/contrib/admin/templates/admin/auth/user/change_password.html ​Line 19
  • ./django/contrib/admin/templates/admin/change_form.html ​Line 36

In each of those cases there are block elements at the end of the line so these seem more like false positives than an actual issues

Proposal for Standard

Given the findings above I think a standard is mostly already there, but just needs to be documented:

  • {{ should be followed by a single space
  • {% should be followed by a single space
  • {% extends %} should always be on line 1
  • {% load %} and there should only be 1 {% load %} statement per file
  • {% block %} probably needs more discussion on what standard should exist

As mentioned above, details of the work are in the comments on the ticket.

I look forward to your feedback

2 Likes

Thank you for picking this up Ryan—great research and writeup. I am excited for a template style guide that projects could adopt. I’d love to work on a formatted tool to match the guide. (I’d also hope to make it auto-upgrade templates, subsuming ideas listed in long-open django-upgrade issues).

The currently proposed standard matches most of my preferences.

To be explicit, you should also list:

  • }} is always preceded by a single space
  • %} is always preceded by a single space

The {% load %} rule description is maybe missing the word “follows”? Like “{% load %} follows and there…”.

Maybe we should allow comments above {% extends %}, since they can be used like a docstring to describe a template’s purpose.

My one preference opposed to the proposal is with {% load %}. I prefer multiple alphabetically sorted {% load %} tags. This style leads to fewer merge conflicts and keeps git blame accurate. I similarly prefer one-import-per-line in Python code and have seen fewer conflicts since adopting this style.

On {% block %}, perhaps we could require {% endblock %} to repeat the block name if not on the same line? This can make longer templates more navigable - “okay, I’ve reached the end of the navigation now…”.

1 Like

I think I broadly agree with Adam’s suggestions here but I more wanted to post that I’d be very happy to see this.

I also wish there was a good formatter available so people - especially reviewers - don’t have to think about this. I’ve tried a couple and do use one at work but they can often cause very weird looking stuff and excessively long lines. I would certainly argue for one if there was one I thought was good enough… for anyone out there looking for an interesting project :slight_smile:

1 Like

I’ve been fairly happy with djhtml, fwiw. It’s not black levels of “there is only one correct way to format a file”, but it’s consistent and I vastly prefer using it to not using it. I’m guessing it’d be not opinionated enough/not black-like enough for some people, but at least it understands DTL syntax, rather than using a Jinja2 formatter and hoping for the best …

1 Like

Thanks for the feedback @adamchainz, @tom, and @rixx!

I agree with @rixx on djhtml. I’ve used it on a few projects and it’s not black it is very helpful.

Would the next steps be to consolidate these in the Coding Style doc page and submit a PR? If so I’ll get to working on that.

Yeah, go for it, please ping me on the PR.

—-

Some more proposals:

  • Inside curly braces, tokens are separated by single spaces, except filters where the | has no spaces around it.
  • Top-level {% block %} tags for an {% extends %} template have no indentation.
1 Like