Open In App

Flask Rendering Templates

Last Updated : 19 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Flask is a lightweight Python web framework that enables developers to build web applications easily. One of its key features is template rendering, which allows dynamic content generation using Jinja2 templating. In this guide, we’ll explore how to render templates in Flask.

Setting up Flask

Setting up a new flask app requires creating and activating a virtual environment and installing flask to it.

Creating virtual environment

Use the command below to create a new virtual environment in recent Python versions.

pythom -m venv venv

Activate the virtual environment

For Windows:

venv\Scripts\activate

For Linux/macOS: source

venv/bin/activate

Install Flask

pip install flask

This will install Flask in the virtual environment created specifically for our project.

Creating a Flask Application

Create a new file app.py and add the following code to create a basic flask app:

Python
from flask import Flask

app = Flask(__name__)

if __name__ == "__main__":
    app.run()

Explanation:

  • Flask(__name__): Initializes the Flask app.
  • app.run(): Starts the server.

Rendering HTML Templates

One of Flask’s powerful features is its ability to render HTML templates using Jinja2. Instead of returning plain strings in routes, we can use render_template() to serve HTML files dynamically.

Create a templates Folder

Flask looks for HTML files in a special directory called templates. Create a folder named templates in your project directory and create the index.html file.

index.html:

Python
<!DOCTYPE html>
<html>
<head>
    <title>Flask App</title>
</head>
<body>
    <h2>Welcome to Flask</h2>
    <p>This is a basic template rendering example.</p>
</body>
</html>

Modify app.py to Render the Template

Updating app.py to use render_template():

Python
from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html")

if __name__ == "__main__":
    app.run()

Explanation:

  • @app.route(“/”): Maps the root URL (/) to the index() function.
  • render_template(“index.html”): Renders the HTML file.

Templating With Jinja2 in Flask

Now, we’ll create a new route for demonstrating the usage of the Jinja template and add it in app.py.

Python
@app.route("/<name>")
def welcome(name):
    return render_template("welcome.html", name=name)

We create a route “/<name>” linked to the welcome function. The <name> part captures any value after / and passes it as a parameter to render_template(). This makes the variable accessible in the template for rendering or modification.

Create a welcome.html file inside the templates folder with the following markup.

HTML
<!DOCTYPE html>
<html>

<head>
    <title>FlaskTest</title>
</head>

<body>
    <h2>Welcome To GFG</h2>
    <h3>Welcome, {{name}}</h3>
</body>

</html>
jinja-template

Using Jinja template

Flask – Jinja Template Inheritance

Instead of reusing full templates, we can inherit them using Jinja blocks. Here’s how:

  • Create a block in a template using {% block <name> %}{% endblock %}.
  • This allows other templates to extend it and replace the block content.
  • In index.html, define a block using {% block body %}{% endblock %}.
  • Everything above {% block body %} stays the same in all templates, while content inside the block can change.
  • The block ends with {% endblock %}, allowing templates to override only specific sections.

templates/index.html 

HTML
<!DOCTYPE html>
<html>
<head>
<title>FlaskTest</title>
</head>
<body>
<h2>Welcome To GFG</h2>
<h4>Flask: Rendering Templates</h4>
<a href="{{ url_for('home') }}">Home</a>
<a href="{{ url_for('index') }}">Index</a>
{% block body %}


<p>This is a Flask application.</p>


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

We exclude <p> tags because everything above {% block body %} and below {% endblock %} is copied. We use absolute URLs with {{ url_for() }}, which dynamically generates URLs by passing the function name as a string.

Create home.html to reuse the body block with the following content.

templates/home.html

HTML
{% extends 'index.html' %}

{% block body %}

<p> This is a home page</p>

{% endblock %}

This extends, not includes, index.html using {% extends ‘file.html’ %}, ensuring the block is correctly placed. Unlike {% include %}, which simply inserts content, extending properly nests the body text.

Let’s add a route for home.html in app.py.

Python
@app.route("/home")
def home():
    return render_template("home.html")

This is a route bound to the “/home” URL with the home function that renders the template “home.html” that we created just right now.

rendering-templates

Demonstrating block and URLs

The URL is dynamically generated, avoiding the need to hardcode template paths. The block correctly inherits from the base template. To verify, check the page source in your browser.

HTML
<!DOCTYPE html>
<html>
<head>
<title>FlaskTest</title>
</head>
<body>
   <h2>Welcome To GFG</h2>
   <h4>Flask: Rendering Templates</h4>
   <a href="/home">Home</a>
   <a href="/">Index</a>
   <a href="/about">About</a>
   <a href="/documentation">Documentation</a>
   
<p> This is a home page</p>
<p>must use extends not include</p>
</body>
</html>

Inducing Logic in Templates

Templates support for loops and if conditions, making them powerful for dynamic content. We can easily render lists from Python in an HTML template.

Using for loops in templates

We’ll create a route /about that binds to the about function, rendering about.html. Before returning the template, we’ll pass a list of dummy strings to render_template().

Python
@app.route("/about")
def about():
    sites = ['twitter', 'facebook', 'instagram', 'whatsapp']
    return render_template("about.html", sites=sites)

We’ve created the /about route, bound to the about function. Inside it, we define a list Sites with dummy strings and pass it to render_template() as sites. You can name it anything, but use the same name in the template.

Let’s create about.html with the following content.

templates/about.html

HTML
{% extends 'index.html' %}
{% block body %}
<ul>
    {% for social in sites %}
    <li>{{ social }}</li>
    {% endfor %}
</ul>
{% endblock %}

We can use for loops in templates inside {% %}, just like in Python. The sites list, passed from the route function, is accessed using {{ }}. Variables use {{ }}, while loops and logic blocks use {% %}.

To make navigation easier, add its URL to index.html like this:

HTML
<!DOCTYPE html>
<html>
<head>
    <title>FlaskTest</title>
</head>
<body>
    <h2>Welcome To GFG</h2>
    <h4>Flask: Rendering Templates</h4>
    <a href="{{ url_for('home') }}">Home</a>
    <a href="{{ url_for('index') }}">Index</a>
    <a href="{{ url_for('about') }}">About</a>
    {% block body %}
    
<p>This is a Flask application.</p>

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

 
This is not mandatory but it creates an accessible link for ease.  

for-loops-in-templates

Demonstrating for loop-in templates

The template dynamically generates the list, which is useful for fetching data from a database in a production app. It also helps automate repetitive tasks that would be tedious to do manually.

If statement in HTML Template in Python Flask

Flask templates also support if-else conditions, allowing for dynamic content. Just like loops, they help create flexible templates.

For example, let’s define a contact route:

  • The URL “contact/<role>” is bound to the contact function.
  • It renders contacts.html, passing role as an argument.
  • We can assign role to another variable, like person, in the template for better readability.
Python
@app.route("/contact/<role>")
def contact(role):
    return render_template("contact.html", person=role)

This creates the route as desired and parses the variable role as a person to the template. Now let us create the template.

template/contact.html

HTML
{% extends 'index.html' %}
{% block body %}
  {% if person == "admin" %}
  
<p> Admin Section </p>
  {% elif person == "maintainer" %}
<p> App Source Page for Maintainer</p>
  {% elif person == "member" %}
<p> Hope you are enjoying our services</p>
  {% else %
<p> Hello, {{ person }}</p>

  {% endif %}
{% endblock %}

In the template, we check the person variable, which comes from the URL and is passed via render_template(). The if-else syntax is similar to Python but enclosed in {% %}. It follows a simple if-elif-else structure to generate HTML based on the value.

if-in-flask

If Statement Demonstration in Flask

The template dynamically renders content based on the role variable in the URL. However, you can’t create a direct link for this since the role must be entered manually.



Next Article

Similar Reads