How To Create Flask Base Template

How To Create Flask Base Template

In Flask just like in most web development frameworks, you can make use of base templates and the extending of templates to reduce repetitive markup. In other words, you can have a base HTML file and have components from that shown on every single webpage. We can refactor some of the markups we have created already in our Flask application in order to make use of templates that extend from other templates and use various blocks to get the layout we want.


templates/base.html

To get started with base templates in Flask, we can add a new file to the project in the templates directory named base.html.

flask base template

In the base.html file, we want to put the markup that typically appears on every page of the site. So things like the DOCTYPE, html tag, head tag, meta tag, title tag, and body tag, should be included here. Then, we use the special templating syntax to designate where markup from other templates will be dynamically inserted at runtime. As an example, here is a start to the base.html file.

flask-tutorial\templates\base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
{% block main %}
{% endblock %}
</body>
</html>

In between the opening and closing body tags, we have {% block main %} and {% endblock %}. This is where we can insert other content dynamically.


Using extends

Now we can visit a different template file like home.html and make use of the extends keyword. When the extends keyword is used, this tells Flask to take any content between {% block main %} and {% endblock %} on this page, and insert it in between the {% block main %} and {% endblock %} on the page it extends from. This means that the highlighted markup below in home.html will get inserted in base.html at runtime.

flask-tutorial\templates\home.html

{% extends 'base.html' %}

{% block main %}
<h1>Make A Short URL</h1>
{% for message in get_flashed_messages() %}
<h2>{{ message }}</h2>
{% endfor %}
<form action="shortenurl" method="post">
    <label for="url">Enter URL</label>
    <input type="url" name="url" value="" required>
    <label for="shortcode">Enter Name</label>
    <input type="text" name="shortcode" value="" required>
    <input type="submit" value="Submit">
</form>
{% endblock %}

Make sure to put single quotes around ‘base.html’ or you might get an error like: “jinja2.exceptions.UndefinedError jinja2.exceptions.UndefinedError: ‘base’ is undefined”


Using include

Another nice approach to reduce repetitive code is to use include statements in Flask. Let’s make a new html file named flash.html and place the markup responsible for displaying flash messages in that file.

flask include template

Inside of that file is the markup removed from home.html.
flask-tutorial\templates\flash.html

{% for message in get_flashed_messages() %}
<h2>{{ message }}</h2>
{% endfor %}

The next step is to include this chunk of code on the page we want it to appear on. This is highlighted here.

flask-tutorial\templates\home.html

{% extends 'base.html' %}

{% block main %}
<h1>Make A Short URL</h1>
{% include 'flash.html' %}
<form action="shortenurl" method="post">
    <label for="url">Enter URL</label>
    <input type="url" name="url" value="" required>
    <label for="shortcode">Enter Name</label>
    <input type="text" name="shortcode" value="" required>
    <input type="submit" value="Submit">
</form>
{% endblock %}

Dynamic Titles

The title tag is now included in the base template. What this means is you can no longer hard code the inner HTML of title unless you want every single page to have the same title. We can update the home page route to pass a title as a variable and then use interpolation in the template to display that variable like so.

flask-tutorial\app.py

@app.route('/')
def home():
    title = 'Make A Short URL'
    return render_template('home.html', title=title)

flask-tutorial\templates\base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
{% block main %}
{% endblock %}
</body>
</html>

How To Use Bootstrap Template In Flask

So far this Flask application has no CSS styling at all. To make it look better, we can use Bootstrap in the templates. Let’s modify the base.html file like so.

flask-tutorial\base.html

<!doctype html>
<html lang="en">
<head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x"
          crossorigin="anonymous">

    <title>{{ title }}</title>
</head>
<body>
{% block main %}
{% endblock %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4"
        crossorigin="anonymous"></script>
</body>
</html>

The home page looks a little cleaner now.

How To Use Bootstrap Template In Flask


Bootstrap Alerts For Flash Messages

Now that Bootstrap is installed in the project, we can make the flash messages much more pleasing to look at for the end-user. A simple addition of a class definition in flash.html should do the trick.

flask-tutorial\templates\flash.html

{% for message in get_flashed_messages() %}
<h2 class="alert alert-info">{{ message }}</h2>
{% endfor %}

It looks to be working quite well.

Learn More About How To Create Flask Base Templates With Bootstrap