2009-01-24

Nested blocks in Django duplication problems

The official instructions and cursory google searches didn't turn up a good explanation, but I've figured it out for myself. I was confused about nesting blocks, sometimes getting no output or getting duplicate output.

In this example the base has a single level of nesting with two sub-blocks.

base.html:

{% block outer %}

{% block inner1 %}
this is inner1
{% endblock inner1 %}


{% block inner2 %}
this is inner2
{% endblock inner2 %}

{% endblock outer %}


This file duplicate the original block structure but adds a comment:
some.html:

{% extends base.html %}

{% block outer %}
{{ block.super }}

new stuff

{% endblock outer %}


The output would be
this is inner1
this is inner 2
new stuff


Moving the 'new stuff' line before the the block.super would swap the order of the output statements. There is no way to interject the new comment inbetween inner1 and inner2 without creating a new block that sits inbetween them in the parent base.html file.



Don't try to do this (which is what I thought to do initially):


{% extends base.html %}

{% block outer %}
{{ block.super }}

new stuff

{% block inner2 %}
new inner2
{% endblock inner2 %}

{% endblock outer %}


It will result in duplication like this:
this is inner1
new inner2
new stuff
new inner2



Instead, the extending file that wants to alter any parent block does it in a non-nested way, don't redefine an inherited block while inside of another inherited block:

{% extends base.html %}

{% block outer %}
{{ block.super }}

new stuff

{% endblock outer %}

{% block inner2 %}
new inner2
{% endblock inner2 %}


And now the output will be without duplication.

this is inner1
new inner2
new stuff



block.super needs to be in there or the redefinition of inner2 won't be applied to anything.

2 comments:

Ivan said...

Crisp and clear. Just what I wanted. Thanks!

Elif said...

Very useful! Thank you.