<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>{% block title %}{% endblock %}</h1>
</body>
</html>
This is my template, more or less. The h1 heading is always the same as the title tag. The above snippet of code is not valid because there can't be two blocks with the same name. How do I handle this without repeating myself?
edit to clarify: I have a ton of child templates which are inherited from this one template, and so making a new {{title}} variable for each template is not a very good solution. Previously I had it set up like this:
base.html:
<title>{% block title %}{% endblock %}</title>
then in base_view.html (extending base.html):
<h1>{% block title %}{% endblock %}</h1>
then in base_object.html (extending base_view.html):
{% block title %}my title goes here{% endblock %}
and it just worked somehow. I refactored my templates so theres just base.html, and base_object.html How can I get this functionality back?
That could work if you're really worried about keeping
title
out of the views and not repeating yourself.It looks like your layout is solid. You have a
base.html
template that defines the basic structure and outer layout for each page in your app. You also havebase_object.html
that extends this template.You'd like each page to have a unique title and a matching h1 (I think). This best way to do this is to define two separate blocks in your base.html template.
In your child templates, you need to override both of these if you'd like them to be identical. I know you feel this is counter-intuitive, but it is necessary due to the way template inheritance is handled in Django.
Source: The Django template language
The children look like this:
If this bothers you, you should set the title from the view for each object as a template variable.
Django strives to keep as much logic out of the template layer as possible. Often a title is determined dynamically from the database, so the view layer is the perfect place to retrieve and set this information. You can still leave the title blank if you'd like to defer to the default title (perhaps set in
base.html
, or you can grab the name of the site from thedjango.contrib.sites
package)Also
{{ block.super }}
may come in handy. This will allow you to combine the contents of the parent block with additional contents from the child. So you could define a title like "Stackoverflow.com" in the base, and setin the child to get a title like "Stackoverflow.com - Ask a Question"
In base.html:
Then, make another "base" layer on top of that called content_base.html (or something):
Now have all your other templates extend content_base.html. Whatever you put in block "title" in all your templates will go into both "title" and "h1" blocks in base.html.
Pass a variable to your template, maybe called title. Then replace your title block with {{ title }}. To pass this into your template in your view make sure you have:
Then in your template you will have:
See also: How to repeat a "block" in a django template