For about a year now, I’ve been harping about using {% block main %}
, and today, I got affirmation that it is the right thing to do. I saw an article posted about it in A List Apart’s feed and started investigating.
So it’s looking likely that we’ll have a <main>
tag soon. I’ll skip over the specifics because you’re probably already using <div class="main">
. It is one of the most common elements and even more so now that .nav
, .header
, and .footer
are now <nav>
<header>
, and <footer>
.
The important thing to remember is there can only be one <main>
tag on a page. And it just so happens that you can only have one {% block main %}
in a Django template (barring some trickery). So how to use it? The obvious way is something like:
{% extends "site_base.html" %}
{% comment %} Don't actually use main like this {% endcomment %}
{% block main %}
<main>
{# Your content #}
</main>
{% endblock %}
But not so fast! Django templates can divided into three categories: base/layout templates, detail/leaf templates, and includes/shared/component templates (which I’ll ignore for the rest of this post). So here’s how your templates should look like. The base, layouts/base.html
:
{% extends "site_base.html" %}
{% block body %}
{% block main_container %}
<main role="main">
{% block main %}{% endblock %}
</main>
{% endblock %}
{% endblock %}
And the leaf:
{% extends "layouts/base.html" %}
{% block main %}
{{ object }}
{% endblock %}
So why have a block immediately surrounding the <main>
? Well you’re going to find it hard to make variations of base templates without it. To extend an existing base, load the structure into {% main_container %}
and re-provide {% block main %}
like this:
{% extends "layouts/base.html" %}
{% block body %}
{% block main_container %}
<div class="row">
<div class="span8">
<main role="main">
{% block main %}{% endblock %}
</main>
</div>
<div class="span4">
<aside>
{% block rail %}{% endblock %}
</aside>
</div>
</div>
{% endblock %}
{% endblock %}
Now you’re guaranteed to have your main content rendered no matter which base you extend because every base template provides a main
block.
And finally, don’t actually use <main>
since it’s only a draft spec. Use <div class="main" role="main">
instead.