Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I correctly inherit templates in flask that use bootstrap?

It seems if I use {% extends "base.html" %} it inherits the template correctly but the navbar doesn't use bootstrap.

If I use {% extends "bootstrap/base.html" %} it doesn't even work. I don't get errors but it just sets the title to Index and then the page is blank.

Another note: The only way I've gotten the navbar to show up is directly putting it inside index.html and using {% extends "bootstrap/base.html" %}

I am using Flask Web Development by Miguel Grinberg and the code is identical except the obvious content.

What am I doing wrong? And does anyone have good resources for slowly jumping into Flask that doesn't just dive in head first? I'm having trouble understanding the little nitpicky details.

base.html:

{% extends "bootstrap/base.html" %}
<html>

<head>
    {% block head %}
    <title>{% block title %}{% endblock %} - MyFlask</title>
    {% endblock %}
</head>

<body>

    {% block navbar %}
        <div class="navbar navbar-inverse" role="navigation">
            <div class="container">
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                        <span class="sr-only">Navbar</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="/">MyFlask</a>
                </div>
                <div class="navbar-collapse collapse">
                    <ul class="nav navbar-nav">
                        <li><a href="/">Home</a></li>
                        <li><a href="/bootstrap"></a></li>
                    </ul>
                </div>
            </div>
        </div>
    {% endblock %}

    {% block content %}
        <div class="container">
            {% block page_content %}{% endblock %}
        </div>
    {% endblock %}

</body>
</html>

index.html:

{% extends "base.html" %}
{% block title %}Index{% endblock %}

{% block page_content %}
    <h3>Session info:</h3>
    <p><b>Browser:</b> {{ browser }}</p>
{% endblock %}
like image 593
Jordan Avatar asked Oct 22 '15 01:10

Jordan


1 Answers

When using the template inheritance it is common to define the structure of the layout in the base template, and then provide the specific details of each child template in the blocks (like content, page_content, etc).

In the above example where the base template itself is a child template (of "bootstrap/base.html"), the same pattern can be used.

Instead of defining HTML tags (like <html>, <head>, etc.) it's better to use the corresponding blocks. Flask bootstrap defines such blocks corresponding to each of these HTML tags, where child templates can override.

So if you change the base.html template as follows, then the index template can use the layout defined in bootstrap/base:

{% extends "bootstrap/base.html" %}

{% block head %}
    {{ super() }}
    <title>{% block title %}{% endblock %} - MyFlask</title>
{% endblock %}

{% block navbar %}
    <div class="navbar navbar-inverse" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Navbar</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">MyFlask</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="/">Home</a></li>
                    <li><a href="/bootstrap"></a></li>
                </ul>
            </div>
        </div>
    </div>
{% endblock %}

{% block content %}
    <div class="container">
        {% block page_content %}{% endblock %}
    </div>
{% endblock %}

Note that in the head block, we are using super() to bring whatever Flask bootstrap has defined in the head block (could be loading CSS, JS files, etc.). This allows the base.html template to customize the head section. However if you do not require this control and only want to specify the title of the page, then you can avoid overwriting head block and just define the title block. To do this change base.html file to start like:

{% extends "bootstrap/base.html" %}

{% block title %}{% block page_name %}{% endblock %} - MyFlask{% endblock %}

Removing {% block head %} ... section. And then modify your index.html template to define the page_name block instead of title:

{% extends "base.html" %}

{% block page_name %}Index{% endblock %}

{% block page_content %}
    <h3>Session info:</h3>
    <p><b>Browser:</b> {{ browser }}</p>
{% endblock %}

Now the title of the index page will be "Index - MyFlask", so you could have a common suffix for the title of all the pages.

Or if you need each page to have their own specific title, you may define the title block in there, overriding the title block in base.html.

like image 55
farzad Avatar answered Oct 11 '22 20:10

farzad