How to repeat a "block" in a django template

I want to use the same {% block %} twice in the same django template. I want this block to appear more than once in my base template:

# base.html
<html>
    <head>
        <title>{% block title %}My Cool Website{% endblock %}</title>
    </head>
    <body>
        <h1>{% block title %}My Cool Website{% endblock %}</h1>
    </body>
</html>

And then extend it:

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}

# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}

I will get an exception, as Django wants the block to appear only once:

TemplateSyntaxError at /

'block' tag with name 'title' appears more than once

A quick and dirty solution would be duplicating the block title into title1 and title2:

# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}

But this is a violation of the DRY principle. It would be very difficult as I have a lot of inheriting templates, and also because I don't wanna go to hell ;-)

Is there any trick or work-around to this problem? How can I repeat the same block in my template, without duplicating all the code?


Solution 1:

Use the Django template macros plugin:

https://gist.github.com/1715202 (django >= 1.4)

or

http://www.djangosnippets.org/snippets/363/ (django < 1.4)

django >= 1.4

# base.html
{% kwacro title %}
    {% block title %}My Cool Website{% endblock %}
{% endkwacro %}

<html>
    <head>
        <title>{% usekwacro title %}</title>
    </head>
    <body>
        <h1>{% usekwacro title %}</h1>
    </body>
</html>

and

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

django < 1.4

# base.html
{% macro title %}
    {% block title %}My Cool Website{% endblock %}
{% endmacro %}

<html>
    <head>
        <title>{% usemacro title %}</title>
    </head>
    <body>
        <h1>{% usemacro title %}</h1>
    </body>
</html>

and

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

Solution 2:

I think that use of the context processor is in this case an overkill. You can easily do this:

#base.html
<html>
    <head>
        <title>{% block title %}My Cool Website{% endblock %}</title>
    </head>
    <body>
        {% block content %}{% endblock %}
    </body>
</html>

and then:

# blog.html
{% extends 'base.html' %}
{% block content %}
    <h1>{% block title %}My Blog{% endblock %}</h1>
    Lorem ipsum here...
{% endblock %}

and so on... Looks like DRY-compatible.

Solution 3:

You probably don't actually want to use a block but rather to just use a variable:

# base.html
<html>
    <head>
        <title>{{ title|default:"My Cool Website" }}</title>
    </head>
    <body>
        <h1>{{ title|default:"My Cool Website" }}</h1>
    </body>
</html>

You then set the title through the context.