Django Block Content

Django Block Content

Block Content in Django is the concept of working with Template Inheritance. As you add more templates to your project, you will notice that a lot of the markup is duplicated. Every template will have an opening <HTML> tag, an opening <head> tag, a closing </head> tag, a closing </HTML> tag and so on and so forth. The general structure of the HTML document stays fairly consistent, while the content inside the structure may change. With Block Content and Template Inheritance, it is possible to define the skeleton HTML template once and then inherit from that base for other templates. In this tutorial, we’ll take a look at how to accomplish that.


templates Folder in Root Project

block content templates folder

The templates folder goes in the main project root if you would like to be able to share the base template across all installed apps for the overall Django project. If you would rather have a unique base template for each app, then you can place a base template in each app itself. For this example, we’re simply putting the base template in the project root. When adding a directory like this in the project root, we need to tell Django how to find this templates folder in the settings.py file like so:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            BASE_DIR / 'templates'
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

base.html in templates Folder

Inside of that templates folder, let’s add a base.html file.

base html template django


Introducing {% block %}

The block tag is used to define a block that can be overridden by child templates. In other words, when you define a block in the base template, you’re saying that this area will be populated with content from a different, child template file. Consider this base.html template that has two blocks defined. One for the title, and one for the content.

templates\base.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>{% block title %} Hello World {% endblock title %}</title>
  </head>
  <body>
    {% block content %}{% endblock content %}
  </body>
</html>

Say Hello To {% extends %}

Once you have your base template, it can be extended in other child templates. The way to do this is with the extends keyword. So in the index.html file we have been working on, we can add that tag at the very top of the file.

goals\templates\goals\index.html

{% extends 'base.html' %} 

{% block title %}Goals{% endblock title %} 

{% block content %}
<ul>
  {% for timeframe in timeframes reversed %} {% if timeframe == 'monthly' %}
  <li><a href="{% url 'namedurl' timeframe %}">{{ timeframe|upper }}</a></li>
  {% else %}
  <li><a href="{% url 'namedurl' timeframe %}">{{ timeframe|capfirst }}</a></li>
  {% endif %} {% endfor %}
</ul>
{% endblock content %}

Notice that in the index.html file we have removed all of the boilerplate skeleton HTML from before. It is no longer needed since when this page loads, it will inherit the HTML found in the base template. We also see those block template tags in this template file as well. We again have a title block and a content block. Any data inside of these blocks will be dynamically injected into the block definitions we created in the base.html template. Visiting the page in a live session shows us the dynamic title and content areas are working.

django template inheritance working

Adding {% extends %} To Other Files

With this new knowledge of how to use {% block %} and {% extends %}, let’s fix the goal.html to also extend the base.html template.

goals\templates\goals\goal.html

{% extends 'base.html' %} 

{% block title %}{{ timeframe|capfirst }} Goal{% endblock title %}

{% block content %}
<h1>{{ timeframe|capfirst|add:' Timeframe' }} goal</h1>
<h2>{{ goal }}</h2>
{% endblock content %}

Also, note that we can use those familiar Django filters in base and child templates with no problem at all.

django base and child template

Django Block Content Summary

Template inheritance is a great feature in the Django Template Language. By using the {% block %} and {% extends %} tags, we saw exactly how to implement this. Also, note that it is possible to have more than one base template if you like. This might be useful if you want to have a slightly different HTML structure for different parts of your application. The important thing to remember is to be sure to extend from the correct template file when using the {% extends %} tag in any child templates.