What’s the Deal With: Django Template Indentation

I like my source code to look good (if at all possible). Django definitely helps with this but you are essentially in a 0 sum game. You make your template code look good or your output HTML source look good, not both it seems.

OK, so in the docs you will first of all come across something like this:

{% for o in some_list %}
    <li class="{% cycle 'row1' 'row2' %}">
        ...
    </li>
{% endfor %}

The template tags start with 0 indentation, in other words at the current level of indentation. Everything inside of those tags are then indented by one level, and normal HTML indentation practices resume.

But then, as soon as you find template tags within HTML in the docs they start to ignore HTML indentation:

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

Every natural instinct makes me want to write:

<ul>
    {% for athlete in athlete_list %}
        <li>{{ athlete.name }}</li>
    {% endfor %}
</ul>

So what is the deal here? I understand that the output HTML will have two levels of indentation between the ul and the li elements:

<ul>
        <li>Marcus</li>
        <li>Chris</li>
        <li>Rob</li>
</ul>

But if we really cared about that we would not indent anything inside a template tag which had 0 indentation already.

No One Does It

I have never seen a good solution to creating dynamic pages with nice looking source code, how hard would it be to add a layer in the template building phase to remove traces of the existence of template tags?

Say for example removing a level of indentation when a nested template tag is used, or removing newlines when a whole bunch of template tags are encountered in a contiguous block.

Ah well. I guess dynamic websites will just be plagued with weird looking source code for ever.

Marcus Whybrow is a student at the University of Nottingham's school of Computer Science. He is a musician, a photographer and a designer. He always has a project on the go and especially enjoys creating web applications using the brilliant Django framework, which he is putting into action at Aware Monitoring in his capacity as a summer intern.


View Comments to What’s the Deal With: Django Template Indentation

  1. by Morpho

    On July 3, 2010 at 10:27 am

    Why do you want you html code to look good? I always wrap my html code in {% spaceless %} tags, which is a big improvement especially with big websites where every byte counts. It doesnt look good at all but its less byte to transfer..

  2. by Marcus Whybrow

    On July 3, 2010 at 10:36 am

    When I started web development the HTML source code was all I had to worry about. I guess old habits die hard.

    Every time I have used the {% spaceless %} tag it seems to do absolutely nothing, maybe I should read up about it in the docs. However my point is really about just straight up Django template indentation standards.

  3. by Morpho

    On July 3, 2010 at 11:01 am

    From the docu:
    Removes whitespace between HTML tags. This includes tab characters and newlines.

    Example usage:
    {% spaceless %}

    Foo

    {% endspaceless %}

    This example would return this HTML:

    Foo

    In my opinion you as a django developer shouldnt worry about html as long as everything gets displayed correctly.

  4. by Nestor

    On July 3, 2010 at 11:11 am

    Morpho: I don't agree with that. When dealing with debugging javascript, w3c validation or accesibility a good indentation helps a lot.

  5. by Morpho

    On July 3, 2010 at 11:23 am

    spaceless doesnt touch javascript. and debugging (firebug, etc) always uses the dom tree, which is already parsed html code. validation and accessibility is a standart. usually we got a final layout first and integrate django template code afterwards.

  6. by Nestor

    On July 3, 2010 at 11:28 am

    Morpho: looks like we are looking at this from different role perspective.
    Some times I have been given an already made site (not yet with django) or new part of a site, like say the forums, and have to make it accesible.
    You are right if the workflow goes like that, but that is not always the case, sadly.

  7. by Morpho

    On July 3, 2010 at 11:33 am

    ok Nestor, i got your point. i dont have that case very often. but in case i use firebug, edit the parsed dom-tree on-the-fly and copy everything in my django templates. that works best for me.

  8. by Marcus Whybrow

    On July 3, 2010 at 11:37 am

    If it were the case that nobody ever needed to look at the HTML code of a site, we should be just be minifying the whole thing. The fact that we don't (in most cases) suggests that generating legible HTML is somewhat important.

  9. by ksamuel

    On July 3, 2010 at 1:42 pm

    Who cares ?

    If the machine read it, it doesn't matter.

    If a human read it, he will use htmltidy or a firefox extension to get a readable output automatically.

    It's really not something to waste your time on.

  10. by Marcus Whybrow

    On July 3, 2010 at 2:38 pm

    If we don't care about the HTML, then we should stop sacrificing the templates indentation for no reason.

  11. by Morpho

    On July 3, 2010 at 2:45 pm

    Django template code should be easy to read. I think thats most importatnt. If you need proper html indentation use http://djangosnippets.org/snippets/172/ or firebug

  12. by Marcus Whybrow

    On July 3, 2010 at 2:51 pm

    I agree. I think template code is much more important since that is where you (as the developer) are spending most of your time.

  13. by Kenneth Love

    On July 3, 2010 at 4:49 pm

    The first example you show, from the books, makes the most sense.

    In the UL, when there are items, indent and print them. This is logical.

    Your example, though, isn't since it automatically introduces a level of indentation regardless of if there are items or not.

    (really the whole thing should be wrapped in an if anyway to prevent an empty UL)

  14. by Marcus Whybrow

    On July 3, 2010 at 5:10 pm

    Right, so you are putting more focus on getting the correct output rather than nicely indented template code?

    Yes you are quite right about wrapping everything in an if statement in order to create valid HTML – validity is a different matter altogether, and an important one.

  15. by Eric Florenzano

    On July 3, 2010 at 6:02 pm

    Jinja2 deals with whitespace (at least partly) by allowing the user to append an – to templatetags: http://jinja.pocoo.org/2/documentation/template...

  16. by Dougal Matthews

    On July 5, 2010 at 7:46 am

    I think I'd have to say that this probably lies in the category of problems that either don't really exist or don't need solving. After all, its not really a problem how the HTML looks as there are plenty of ways to view it and thus its not really a problem.

    Besides, extra indentation hardly makes the HTML unreadable. Not like the output some websites create. Try looking at the output of a .NET site for example.

  17. by Henrique

    On July 6, 2010 at 2:22 am

    Just make sure your document is not broken. The browser doesn't care about the pretty indentation of your HTML. In fact, you *should* be minifing the most you can, as it's actually a site tuning recommendation, and even factors into Google's pagerank.

  18. by Harro van der Klauw

    On July 6, 2010 at 12:06 pm

    Maybe write a middleware that does post processing to tidy the html.

  19. by Marcus Whybrow

    On July 6, 2010 at 12:09 pm

    Yer that sounds like an efficient way to do things, what would be really cool is if the code was minified when DEBUG = False and tidied when DEBUG = True.

  20. by Robert Frost

    On July 7, 2010 at 11:10 am

    If you use spaceless as compression instead of gzip you, my good sir, are a retard. Ta.

  21. by Jan Rzepecki

    On July 12, 2010 at 10:16 am

    Maybe let's change to different approach, if visual readablity of code matters.
    http://github.com/jessemiller/HamlPy

  22. by Marcus Whybrow

    On July 12, 2010 at 11:33 am

    Judging by the github README this:

    %ul#atheletes    - for athelete in athelete_list        %li.athelete= athelete.name

    still turns into this:

    <ul id='atheletes'>    {% for athelete in athelete_list %}        <li class='athelete'>{{ athelete.name }}</li>    {% endfor %}</ul>

    Which doesn't solve the HTML indentation problem. However something like this could be the answer, and I have not looked at HamlPy in enough detail to know that it is not that answer.

blog comments powered by Disqus