Peter Kim
Peter Kim

Reputation: 45

Django block page title

I'm trying to create a custom page title for each page but I've not been successfull. The following is the general setup for all my html pages (And what I thought would work; it doesn't) and would appreciate any solutions.

head.html

something something
<title>{% block title %}Default Value{% endblock title %}</title>
something something

base.html

<!DOCTYPE html>
<html>

{% include "head.html" %}

<body>
    {% include 'header.html' %}

    {% block content %}
    {% endblock content %}

    {% include 'footer.html' %}
    {% include 'scripts.html' %}
</body>
</html>

404 html file

{% extends 'base.html' %}
{% load static %}

{% block title %}404{% endblock title %}

{% block content %}
<div id="main404">
        <div class="fof">
                <h1>Error 404 :(</h1>
        </div>
</div>
{% endblock content %}

Currently it still displays the default value indicated in head.html. I would like to customise the page title of each page using the block as attempted above.

Thanks.

Upvotes: 2

Views: 5919

Answers (3)

Hemant
Hemant

Reputation: 1166

one way of doing this while keeping your file structure as it is would be to send title as parameter in django's include method as follows:

Update your files as follows:

base.html

create a new block named headcontent and include head.html with default title

<!DOCTYPE html>
<html>

{% block headcontent %}{% include head.html with title="Default Title" %}{% endblock %}
<body>
    {% include 'header.html' %}
    {% block content %}
    {% endblock content %}
    {% include 'footer.html' %}
    {% include 'scripts.html' %}
</body>

</html>

404.html

provide value to headcontent block as head.html with title of your desire, 404 in this case.

{% extends 'base.html' %}
{% load static %}

{% block headcontent %}{% include head.html with title="404" %}{% endblock %}
{% block content %}
<div id="main404">
        <div class="fof">
                <h1>Error 404 :(</h1>
        </div>
</div>
{% endblock content %}

head.html

something something
<title>{{title}}</title>
something something

To know more about using include with parameters check include in django template

Upvotes: 1

schillingt
schillingt

Reputation: 13731

The block tag can only be overriden by children templates, those that use the extends tag. Your block tag for the title is nested in a include template statement (head.html). If you have a large head block that you need to include for other templates then I can see inheritance being helpful.

head.html

something something
<title>{% block title %}Default Value{% endblock title %}</title>
something something

head_404.html

{% extends 'head.html' %}
{% block title %}404{% endblock %}

base.html

<!DOCTYPE html>
<html>

{% block head %}
    {% include "head.html" %}
{% endblock %}

<body>
    {% include 'header.html' %}

    {% block content %}
    {% endblock content %}

    {% include 'footer.html' %}
    {% include 'scripts.html' %}
</body>
</html>

404.html

{% extends 'base.html' %}
{% load static %}

{% block head %}
    {% include "head_404.html" %}
{% endblock %}

{% block content %}
<div id="main404">
        <div class="fof">
                <h1>Error 404 :(</h1>
        </div>
</div>
{% endblock content %}

You could skip the head_404.html file and simply define the head children tags in the 404.html template as well.

{% extends 'base.html' %}
{% load static %}

{% block head %}

    ... stuff

    <title>404</title>

{% endblock %}

{% block content %}
<div id="main404">
        <div class="fof">
                <h1>Error 404 :(</h1>
        </div>
</div>
{% endblock content %}

Upvotes: 0

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21807

The 404 html file extends base.html not head.html meaning it won't fill the blocks of head.html. head.html is included into base.html meaning it is compiled and rendered separately and is not extended by the template which is extending base.html.
As referenced from Django documentation:

The include tag should be considered as an implementation of “render this subtemplate and include the HTML”, not as “parse this subtemplate and include its contents as if it were part of the parent”. This means that there is no shared state between included templates – each include is a completely independent rendering process.

The simplest way would be to put the block in base.html:

<!DOCTYPE html>
<html>

<head>
    something something
    <title>{% block title %}Default Value{% endblock title %}</title>
    something something
</head>
<body>
    {% include 'header.html' %}

    {% block content %}
    {% endblock content %}

    {% include 'footer.html' %}
    {% include 'scripts.html' %}
</body>
</html>

Upvotes: 3

Related Questions