Serafeim
Serafeim

Reputation: 15104

Django template inheritance - How to use the same content for different blocks

I've the following structure in my django templates

I've a theme_base.html which other templates inherit from:

[...]
<title>{% block page_title_header %}{% endblock %}</title>
[...]
<h1>{% block page_title_body %}{% endblock %}</h1>

Now, most pages have the same page_title for their header and base, so I need to do something like this in my normal templates:

{% block page_title_header %}Page title of current page{% endblock %}
{% block page_title_body %}Page title of current page{% endblock %}

This is not DRY and most of the times I forget to update page_title_header :(

Could you recommend a DRY way to pass the page title (of different each page, so I can't use a default value) to both blocks ?

Update: After a discussion in comments, I believe that the {% with %} template tag would be what I need to use, to do something like this:

{% with "Page title" as title %}
    {% block page_title_header %}{{ title }}{% endblock %}
    {% block page_title_body %}{{ title }}{% endblock %}
{% endwith %}

Unfortuanately, the above is not working, title is not passed to the block !! If I remove the {% block %} and do something like

{% with "Page title" as title %}
    Title is {{ title }}
{% endwith %}

it will work fine. Do you know what could be the problem ? TIA

Upvotes: 1

Views: 1468

Answers (3)

Carlos H Romano
Carlos H Romano

Reputation: 626

Use block.super. Example:

{% block page_title %}
    {% with "foo" as title %}
        {{ block.super }}
    {% endwith %}
{% endblock %}

Upvotes: 0

cdvv7788
cdvv7788

Reputation: 2099

Try:

<title>{% block page_title_header %}
{% if somevar_title %}
{{ somevar_title }}
{% else %}
Default title
{% endif %}
{% endblock %}</title>

And put somevar_title in your context. In your view:

context = {'somevar_title': Page.objects.get(pk=something).title}
return render(request, self.template_name, context)

You just have to remember to add title to your context on every view that is going to use the template. You could also update the context with class based views:

class MyClass(TemplateView):
    def get_context_data(self, **kwargs):
        context = super(MyClass, self).get_context_data(**kwargs)
        #get your title here...whatever you need it to be
        context['somevar_title'] = Something_to_get_my_title
        return context

Then, if you are getting your title from a slug or some way that can be resolved in a generic way just subclass MyClass and you will have the variable in the context. For example, using something like Page.objects.get(pk=kwargs.get('page_id')) could do the trick (don't forget to add logic to handle non valid id's).

Upvotes: 1

Selcuk
Selcuk

Reputation: 59445

You can specify a default value in your blocks, such as:

[...]
<title>{% block page_title_header %}Page title{% endblock %}</title>
[...]
<h1>{% block page_title_body %}Page title{% endblock %}</h1>

When you omit these blocks in your normal templates, default values will be used.

Upvotes: 1

Related Questions