1

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

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

I'm aware of that. The problem is that every template has a different title! I'll try to rephrase my question to make it more clear...
1

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).

7 Comments

I've thought of this (using a context variable) however this probably adds more work to my templates/views than just repeating the title (as I was doing till now), since I'd need to create a PageTitleMixin with your proposed get_context_data with the difference that instead of context['somevar_title'] = Something_to_get_my_title I'd use context['somevar_title'] = self.page_title. And for each CBV that inherits from PageTitleMixin I'd need to add a page_title attribute. That's a nice solution, however I'd really prefer doing it only using templates (if possible).
To make it with only templates, you need some way to access the information at some point. It must be in the db, the url, somewhere. Also, the way i put it, as long as you get the title in the same way always (some field of some model in the database i.e.) you can just subclass MyClass and it will work. You don't need to define a page_title per view. Where are you storing your titles?
Right now? Inside the templates! Each template/view has its own title, for example "Profile detail", "Profile update" etc... That's why I mentioned one title per view...
I mean, you can't be planning to get them magically, you must be wanting to take them out of somewhere...some model, some url, somewhere...
Actually, as I said before most of my templates have a hard-coded title in the template. And I need to write it twice! Thats what I want to avoid!
|
0

Use block.super. Example:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.