Flask tutorial #2 : Templates

Swetha Ganapathi Raman
3 min read3 days ago

--

This tutorial is part of a series on building a Flask web application. For context, please refer to other blogs in this series:

In this tutorial, we will focus on building a landing page using templates and implementing template inheritance.

Objectives

  1. Create a landing page using templates.
  2. Implement template inheritance.

Template basics

In the previous blog, we created a basic Flask route that returned a simple “Hello world” string . However, real world web applications have more complex pages with dynamic content and we need a more structured approach to manage the presentation of our content. Flask’s templating engine provides this structure, allowing us to create reusable and dynamic web pages.

In Flask, the files that contain the structure and layout of the web pages are called as templates. They are typically in HTML and can include special Jinja syntax to dynamically inject data into the HTML files and create more complex logic. Jinja is a templating language that allows to embed python like code within the HTML.

Templates are typically stored in a separate templates directory within the application package.

(venv)$ mkdir smartcookie/templates

Let us now create our index page template .

smartcookielearner/smartcookie/templates/index.html

<!doctype html>
<html>
<head>
<title>{{title}} - Smart Cookie Learner</title>
</head>
<body>
<h1>Welcome to Smart Cookie Learner</h1>
<h2><i>Take quizzes, practice coding and get AI-powered assistance
all in one place.
</i></h2>
</body>
</html>

This is a simple HTML page. It has a placeholder for the dynamic content, enclosed in {{ … }} sections. These placeholders represent the parts of the page that are variables and will only be known during runtime.

To generate the final HTML page from the template, we will modify the view function in routes.py to use Flask’s render_template() function.

The render_template function leverages Jinja, which dynamically replaces any placeholders enclosed in {{ … }} in the template file with the values provided as arguments to the render_template function.

from flask import render_template
from smartcookie import app

@app.route('/')
@app.route('/index')
def index():
return render_template('index.html', title="Home")

Try running this new version of the application to see how the template works. You will notice that the title of the index page would now say Home — Smart Cookie Learner.

Templates can also support control statements, given inside {% ... %} blocks. The next version of the index.html adds a conditional statement.

<!doctype html>
<html>
<head>
{% if title %}
<title>{{title}} - Smart Cookie Learner</title>
{% else %}
<title>Welcome to Smart Cookie Learner</title>
{% endif %}
</head>
<body>
<h1>Welcome to Smart Cookie Learner</h1>
<h2><i>Take quizzes, practice coding and get AI-powered assistance
all in one place.
</i></h2>
</body>
</html>

Now we have added a conditional statement to the template. If the view function does not pass a value to the title placeholder variable, we use a default value.

Template inheritance

Many web pages in an application typically share common elements like headers, navigation bars etc. Repeating this code across multiple HTML files can be cumbersome and error prone. Jinja has a template inheritance feature that specifically addresses the problem. Using this feature, we can move all the common parts of the different pages to a base template, from which all other templates can be derived.

Let us now create a base template called base.html

smartcookielearner/smartcookie/templates/base.html

<!doctype html>
<html>
<head>
{% if title %}
<title>{{ title }} - Smart Cookie Learner</title>
{% else %}
<title>Smart Cookie Learner</title>
{% endif %}
</head>
<body>
<h1>Welcome to Smart Cookie Learner</h1>

{% block content %}

{% endblock content %}
</body>
</head>
</html>

The base.html includes the Jinja placeholders for title which will be replaced with actual values during rendering. It also defines a content block using {% block blockname %} {% endblock %} syntax. Blocks can have default content that child templates can override if needed.

Now, we can simplify index.html by inheriting it from base.html

smartcookielearner/smartcookie/templates/index.html

{% extends "base.html" %}

{% block content %}
<h2><i>Take quizzes, practice coding and get AI-powered assistance all
in one place.</i></h2>
{% endblock %}

The child template starts with {% extends "base.html"%} to inherit from the base template. We only need to define the blocks we would like to override or fill in the child template. We can also add new blocks specific to this template if needed.

For the complete code, please refer to this Github repo.

--

--

Swetha Ganapathi Raman

I am a lifelong learner and educator. I teach coding to students in middle and high school. https://smartcookielearner.com