Open In App

Flask Rendering Templates

Improve
Improve
Like Article
Like
Save
Share
Report

Flask is a backend web framework based on the Python programming language. It basically allows the creation of web applications in a Pythonic syntax and concepts. With Flask, we can use Python libraries and tools in our web applications. Using Flask we can set up a web server to load up some basic HTML templates along with Jinja2 templating syntax. In this article, we will see how we can render the HTML templates in Flask.

Rendering a Template in a Flask Application

Setting up Flask is quite easy. We can use a virtual environment to create an isolated environment for our project and then install the Python packages in that environment. After that, we set up the environment variables for running Flask on the local machine. This tutorial assumes that you have a Python environment configured, if not please follow through for setting up Python and pip on your system. Once you are done, you are ready to develop Flask applications.

Setting up the Virtual Environment

To set up a virtual environment, we can make use of the Python Package Manager “pip” to install the “virtualenv” package.

pip install virtualenv

This will install the package “virtualenv” on your machine. The pip command can be different on the version of your Python installed so please do look at the different syntax of the pip for your version here.

Creating Virtual Environment: 

After the package has been installed we need to create a virtual environment in our project folder. So you can locate an empty folder where you want to create the Flask application or create an empty folder in your desired path. To create the environment we simply use the following command.

virtualenv venv

Here, venv is the name of the environment, after this command has been executed, you will see a folder named “venv” in the current folder. The name “venv” can be anything(“env”) you like but it is standard to reference a virtual environment at a production level. 

Activating Virtual Environment: 

Now after the virtual env has been set up and created, we can activate it by using the commands in CMD\Powershell or Terminal:

Note: You need to be in the same folder as the “venv” folder.

For Windows:

venv\Scripts\activate

For Linux/macOS:

source venv/bin/activate

This should activate the virtualenv with “(venv)” before the command prompt. 

Screenshot of the entire virtualenv setup

As we can see we have successfully created the virtualenv in Windows Operating System, in Linux/macOS the process is quite similar. The (venv) is indicating the current instance of the terminal/CMD is in a virtual environment, anything installed in the current instance of a terminal using pip will be stored in the venv folder without affecting the entire system. 

Installing Flask: 

After the virtual environment has been set up, we can simply install Flask with the following command:

pip install flask

This should install the actual Flask Python package in the virtual environment.

Adding Flask to Environment Variables: We need to create an app for Flask to set it as the starting point of our application. We can achieve this by creating a file called “server.py” You can call this anything you like, but keep it consistent with other Flask projects you create. Inside the server.py paste the following code:

Python




from flask import Flask
 
app = Flask(__name__)
 
if __name__ == "__main__":
    app.run()


This is the code for actually running and creating the Flask app. This is so-called the entry point of a Flask web server. As you can see we are importing the Flask module and instantiating with the current file name in “Flask(__name__)”. Hence after the check, we are running a function called run().

After this, we need to set the file as the Flask app to the environment variable.

For Windows:

set FLASK_APP=server

For Linux/macOS:

export FLASK_APP=server

Now, this will set up the Flask starting point to that file we created, so once we start the server the Flask server will find the way to the file “server.py”

To run the server, enter the command :

flask run

This will run the server and how smartly it detected the server.py file as our actual flask app. If you go to the URL “http://localhost:5000”, you would see nothing than a Not Found message this is because we have not configured our web server to serve anything just yet. You can press CTRL + C to stop the server

Flask set up for webserver

Creating Templates in a Flask Application

Now, we can move on to the goal of this article i.e. to render the template. To do that we need to first create the templates, you can use any HTML template but for simplicity, I am going with a basic HTML template. Before that, create a folder called “templates” in the current folder. Inside this “templates” folder, all of the templates will be residing. Now let us create a basic HTML template:  This template must have some Jinja blocks that can be optionally replaced later. We start with a single block called the body.

templates\index.html

HTML




<!DOCTYPE html>
<html>
 
<head>
    <title>FlaskTest</title>
</head>
 
<body>
    <h2>Welcome To GFG</h2>
    <h4>Flask: Rendering Templates</h4>
 <!-- this section can be replaced by a child document -->  
{% block body %}
 
 
<p>This is a Flask application.</p>
 
 
{% endblock %}
 
 
</body>
 
</html>


Adding Routes and Rendering Templates

A route is a mapping of a URL with a function or any other piece of code to be rendered on the webserver. In the Flask, we use the function decorate @app.route to indicate that the function is bound with the URL provided in the parameter of the route function.

Creating the basic route: In this case, we are binding the URL “/” which is the base URL for the server with the function “index”, you can call it whatever you like but it makes more sense to call it index here. The function simply returns something here it calls the function render_template. The render_template finds the app by default in the templates folder. So, we just need to provide the name of the template instead of the entire path to the template. The index function renders a template index.html and hence we see the result in the browser.

Now, we need a way to actually link the template with a specific route or URL. This means whenever the user goes to a specific URL then a specific template should be rendered or generated. Now, we need to change the “server.py” with the following:

Python




from flask import Flask, render_template
 
app = Flask(__name__)
 
 
@app.route("/")
def index():
    return render_template("index.html")
 
  if __name__ == "__main__":
    app.run()


Output:

We have imported the render_template function from the Flask module and added a route.

render the basic template

Templating With Jinja2 in Flask

Now, we’ll create a new route for demonstrating the usage of the Jinja template. We need to add the route, so just add one more chunk of the code to the “server.py file”

Python




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


Now, this might look pretty easy to understand, we are simply creating a route “/<name>” which will be bound to the welcome function. The “<name>” is standing for anything after the “/”. So we take that as the parameter to our function and pass it to the render_template function as name. So, after passing the variable name in the render_template function, it would be accessible in the template for us to render that variable. You can even perform an operation on the variable and then parse it.

No, we need to create another template called “welcome.html” inside the template folder. This file should contain the following markup

HTML




<!DOCTYPE html>
<html>
 
<head>
    <title>FlaskTest</title>
</head>
 
<body>
    <h2>Welcome To GFG</h2>
    <h3>Welcome, {{name}}</h3>
</body>
 
</html>


Using Jinja template

Flask – Jinja Template Inheritance Example

Now, we need a way to actually inherit some templates instead of reusing them, we can do that by creating the blocks in Jinja. They allow us to create a template block and we can use them in other templates with the name given to the block. 

So, let us re-use our “index.html” and create a block in there. T do that we use “{% block <name> %} (where name = ‘body’) to start the block, this will take everything above it and store it in a virtual block of template, to end the block you simply use “{% endblock %}” this will copy everything below it. 

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>


So, here we are not including the <p> tags as everything below the {% endblock %} and everything above the {% block body %} tag is copied. We are also using absolute URLs. The URLs are dynamic and quite easy to understand. We enclose them in “{{ }}” as part of the Jinja2 syntax. The url_for function reverses the entire URL for us, we just have to pass the name of the function as a string as a parameter to the function.

Now, we’ll create another template to reuse this created block “body”, let’s create the template “home.html” with the following contents:

templates/home.html

HTML




{% extends 'index.html' %}
 
{% block body %}
 
<p> This is a home page</p>
 
{% endblock %}


This looks like a two-liner but will also extend (not include) the index.html. This is by using the {% extends <file.html> %} tags, they parse the block into the mentioned template. After this, we can add the things we want. If you use the include tag it will not put the replacement paragraph in the correct place on the index.html page. It will create an invalid HTML file, but since the browser is very forgiving you will not notice unless you look at the source generated. The body text must be properly nested.

Finally, the piece left here is the route to home.html, so let’s create that as well. Let’s add another route to the “server.py file”

Python




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


So, 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.

Demonstrating block and URLs

As we can see the URL generated is dynamic, otherwise, we would have to hardcode both the template page paths. And also the block is working and inheriting the template as provided in the base templates. Open the page source in the browser to check it is properly formed 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: We can use for loops if conditions in templates. this is such a great feature to leverage on. We can create some great dynamic templates without much of a hassle. Let us create a list in Python and try to render that on an HTML template. 

Using for loops in templates: For that, we will create another route, this time at “/about”, this route will bind to the function about that renders the template “about.html” but we will add some more things before returning from the function. We will create a list of some dummy strings and then parse them to the render_template function.

Python




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


So, we have created the route at “/about” bound to the about function. Inside that function, we are first creating the list “Sites” with some dummy strings and finally while returning, we parse them to the render_template function as sites, you can call anything you like but remember to use that name in the templates. Now, to create the templates, we’ll create the template “about.html” with the following contents:

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 enclosed in “{% %}” we can call them in a regular Pythonic way. The sites are the variable(list) that we parsed in the route function. We can again use the iterator as a variable enclosed in “{{ }}”. This is like joining the puzzle pieces, the values of variables are accessed with “{{ }}”, and any other structures or blocks are enclosed in “{% %}. 

Now to make it more accessible you can add its URL to the index.html like so:

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.  

Demonstrating for loop-in templates

As we can see it has dynamically created all the lists in the template. This can be used for fetching the data from the database if the app is production ready. Also, it can be used to create certain repetitive tasks or data which is very hard to do them manually. 

Corrected extends file

This correctly defined extends file removed the placeholder paragraph and replaces it in the body of the HTML.

If statement in HTML Template in Python Flask

We can even use if-else conditions in flask templates. Similar to the syntax for the for loops we can leverage that to create dynamic templates. Let’s see an example of a role for a website.

Let’s build the route for the section contact. This URL is “contact/<role>”, which is bound to the function contact which renders a template called “contacts.html”. this takes in the argument as role. Now we can see some changes here, this is just semantic changes nothing new, we can use the variable person as a different name in the template which was assigned as the values of the role.

Python




@app.route("/contact/<role>")
def contact(role):
    return render_template("contact.html", person=role)


So, 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 %}


So, in the template, we are checking the value of the variable person which is obtained from the URL and parsed from the render_template function. The if-else syntax is similar to Python with just “{% %}” enclosed. The code is quite self-explanatory as we create if-elif and else ladder, checking for a value and creating the HTML elements as per the requirement. 

 

So, we can see that the template is rendering the contents as per the role variable passed in the URL. Don’t try to create a URL link for this as it would not work since we need to enter the role variable manually. There needs to be some workaround done to use it.

So that was about using and rendering the templates in Flask. We have leveraged the Jinja templating syntax with Python to create some dynamic templates. 



Last Updated : 21 Jun, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads