8

In files that contain multiple languages (ie. template files), are there any best practises regarding indentation?

I mostly use this:

<div>
    IF FOO
        <div>
            <p>contents>
        </div>
    END FOO
</div>

Indent for every new block, regardless of language. This has a few disadvantages, though. In more complex files it can break the indentation of either language:

<div>
    IF FOO
        <div someattribute>
    ELSE
        <div otherattribute>
    END FOO
        <p>content</p>
    </div>
</div>

I've also seen this used:

<div>
    IF FOO
    <div>
       <p>contents>
    </div>
    END FOO
</div>

Ie. indent only one language. This has the advantage of always being consistent, but in more complex files can almost completely hide some implementation details, like a block being conditional.

The goal here is obviously maximizing readability.

gnat
  • 21,442
  • 29
  • 112
  • 288
Celos
  • 267
  • 1
  • 5
  • 1
    +1: interesting question. I'll see if I can write up my (experience-based) opinion later today. – Sjoerd Job Postmus Jan 15 '16 at 08:22
  • @SjoerdJobPostmus No, it is not. The coding standard should tell what identation to use. – BЈовић Jan 15 '16 at 08:50
  • Yes, it is. It needs to be answered before defining coding standards about it. – Florian F Jan 15 '16 at 09:39
  • 1
    @BЈовић, what if there is no coding standard? What if you are the one creating the coding standard? *Someone* has to think about this and decide a solution. In any case the question of whether it is "interesting" is entirely subjective. –  Jan 15 '16 at 09:39
  • @FlorianF So, the question is polling for opinions? In such case, it is highly subjective. I may like the first, you the second, Celos the third, and every answer is valid. – BЈовић Jan 15 '16 at 10:06
  • 1
    The question is about best practices. What experienced people do in this matter? What are the pros and cons of the various options? It is indeed subjective, there is no right and wrong, people follow their taste, but good ideas are likely to spread. – Florian F Jan 15 '16 at 17:25
  • @BЈовић: Indeed. And that's why the question is interesting for those writing coding standards (or, working on a private project). – Sjoerd Job Postmus Jan 15 '16 at 18:55
  • HTML doesn't require indentation, so you shouldn't worry about "breaking" it. Do whatever works for you. For example, if you have a
    that spans a long area, I think there's personally little point in indenting that at all because it doesn't improve readability of the part I'm maintaining (the stuff in the div tags).
    – Brandin Jan 16 '16 at 07:00
  • @Brandin, hardly any language *requires* indentation. The question is what one should do for optimal readability. HTML is a rather messy case. But most would agreee that at least some indentation in HTML is a good thing. –  Jan 20 '16 at 08:27

3 Answers3

11

In my opinion, the main principle for good coding is minimize the intermixture of code.

Two-language files are inherently a mess to work with. Your priority should be to minimize the extent to which the two languages are intertwined.

For example, in a template file, the logic implemented by the templating language should be kept at a bare minimum. Whenever possible, move logic elsewhere and just present a value in the templating file.

Even something like your example:

<div>
    IF FOO
        <div someattribute>
    ELSE
        <div otherattribute>
    END FOO
        <p>content</p>
    </div> 
</div>

Could be better implemented as

<div>
    <div [FOO_ATTRIBUTE]>
        <p>content</p>
    </div> 
</div>

with the attribute to use calculated elsewhere. In this case, then, I would let readability of the file's main language be the driver of the indentation strategy. I wouldn't indent the templating language, and any templating code complex enough to need indentation is probably badly designed.

5

This is one of the primary reasons for avoiding systems that mix two languages together like this. It can get really difficult to check how the control flow of the outer language affects the block structure of the inner language, and when you can't see that, bugs happen.

I prefer to keep them separated and when generating output in another structured language always use a template system that respects the structuring of the language and doesn't require control flow blocks for common tasks.

Jules
  • 17,614
  • 2
  • 33
  • 63
3

(As promised, my experience-based opinion.)

First of all, if you can prevent it: do not mix languages, whenever possible.

As per your example, it seems like you are mostly wondering about how it should be done in a templating language mixed with HTML, which I will cover. (Another case would be building SQL using another programming language, which would require completely different rules).

As an example, I'll cover Django (but PHP, Twig, etc) work mostly the same. Django has logical blocks in the templates (open {% tag %}, closing {% endtag %}). HTML has logical blocks (open <tag>, closing </tag>). Here I mostly follow this rule: increment after an open tag, decrement after a closing tag. Another rule I keep: make sure that the content of a Django block is well-formatted HTML.

As per your example, in my opinion this is very wrong:

<div>
    IF FOO
        <div someattribute>
    ELSE
        <div otherattribute>
    END FOO
        <p>content</p>
    </div>
</div>

Why? Because the content of the IF is not a well-formatted HTML. What should it look like than?

<div>
    <div
        IF FOO
            someattribute
        ELSE
            otherattribute
        END FOO
    >
        <p>Content</p>
    </div>
</div>

(Because your template language does not have nice parsable syntax, we need the new-lines. In Django, I'd write)

<div>
    <div {% if foo %}someattribute{% else %}otherattribute{% endif %}>
        <p>Content</p>
    </div>
</div>

As an added benefit, imagine that the <div> has 7 attributes, 1 of which is decided upon based a specific condition. Or worse: what if it has 3 attributes each of which is dependent on a condition. That would give 8 different tags.

Keeping in mind the "rule" to keep the content of all blocks well-formatted within that scope, you do not have to worry about breaking the indent of either language.

Another point which I would like to cover (though slightly off-topic): If the opening and closing tags are on different lines, they should be the only tag on that line.

Wrong:

<ul>
    <li>This is something <a href="http://programmers.stackexchange.com">Usefull</a>
    </i>
</ul>

Instead, prefer

<ul>
    <li>This is something <a href="http://programmers.stackexchange.com">Usefull</a></li>
</ul>

or

<ul>
    <li>
        This is something <a href="http://programmers.stackexchange.com">Usefull</a>
    </li>
</ul>

(Warning: advanced usage): Sometimes you have multiple wrapping tags, you may (not must) consider this as one tag:

<ul>
    <li><div id="something"><span class="like this">
        Something like this
    </span></div></li>
</ul>

However, preferably don't mix languages (host/guest) when doing this. And preferably don't do this with for loops. And don't do this with .

TL;DR for your specific question.

  • You have a 'host' (eg. Django templating) and 'guest' language (eg. HTML). Make sure the host language blocks always contain correctly formatted guest language blocks.
  • The opening of each block should increment the indentation, the closing of each block should line up with the opening.

And the general note which I should add (as always): use your own judgement. Know when to deviate.

Sjoerd Job Postmus
  • 1,814
  • 1
  • 10
  • 12