Flask offers different ways to show data to the user. The most common and easiest way is to use templates. Templates are files that contain static data as well as placeholders for dynamic data. We can design templates using HTML, CSS, and JavaScript.
In out previous tutorial, we have seen how to create a simple Flask application. If you are new to Flask, you can read "Getting Started with Flask" tutorial to learn the basics of Flask.

By default, "templates" folder is used to store html files for templates. We can crate a folder named "templates" in the same directory as our application and store html files in it.


Now, let's create a simple a simple flask server and HTML template file home.html with some basic HTML tags.
# main.py
from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == '__main__':
    app.run(debug=True)
<!-- templates/home.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
    <h1>Flask Templates</h1>
    <p>Hello to Flask templates.</p>
</body>
</html>
Now, our folder structure looks like this:
 
templates
    home.html
main.py

Now, lets run the application and see the output. Open http://localhost:5000/ in the browser and you will see the following output. This way we can render HTML templates in Flask.

img01

Jinj2 Template

Currently, this template has no dynamic data. Let's see how to pass dynamic data to the template. We can use Jinja2 template engine to pass dynamic data to the template.
Jinja2 is a template engine for Python and is default template engine for Flask. It is fully featured and helps to implement different types of logic in templates. For more details, read Jinja2 documentation.
https://jinja.palletsprojects.com/en/2.11.x/
 
Jinja uses double curly braces {{  }} to render dynamic data. We can pass variables in curly braces {{ variable }} to render the value of the variable. We can pass variables with render_template() function to the template. Let's see an example.
 
Now, lets send additional data to render_template() method and modify the home.html file to show dynamic data in the template.
 
# main.py
@app.route('/')
def home():
    message = 'Hello World'
    return render_template('home.html', message=message)
<!-- templates/home.html -->
<!-- In this example, we only modify body data -->
<body>
    <h1>Flask Templates</h1>
    <p>{{ message }}</p>

    <!-- We can also use variable methods -->
    <p>{{ message.upper() }}</p>

    <!-- Or also in this case, string slicing -->
    <p>{{ message[:5] }}</p>
</body>

Basic

We can pass multiple variables with different data types like string, integer, float, boolean etc to the template like given below.
@app.route('/')
def home():
    return render_template('home.html', name='John', age=25, weight=65.5)
We can render values using curly braces in the template like example below.
<!-- In this example, we only modify body data -->
<body>
    <p>Name: {{ name }}</p>

    <!-- We can also use variable methods -->
    <p>Age: {{ age }}</p>

    <!-- Or also in this case, string slicing -->
    <p>Weight: {{ weight }}</p>
</body>
We can pass as many variables as we want to the template. App will restart automatically when we save the changes. Now, refresh the browser and you will see the following output.
img01

Lists

We can pass any type of data to the template like list, dictionary, or any other data type. Let's see an example, where we can pass any list to template and render the list items in the template.
@app.route('/lists')
def lists_view():
    fruits = ['Apple', 'Orange', 'Banana']

    # Nested list
    numbers = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    
    return render_template('lists.html', fruits=fruits, numbers=numbers)

To render list, we can use for loop in template. It is a little different from Python for loop as we need to use endfor keyword to end the loop. In Jinja2, for expression is written in {% %} as {% for item in list %} and endfor is written as {% endfor %}. Let's write html code to render the list and a nested list.

<!-- templates/lists.html -->
<body>
    <h1>Flask Templates - Lists</h1>
    <ul>
        <!-- We can use for loops to iterate over lists -->
        {% for item in fruits %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>

    <!-- Nested For Loop -->
    <table>
        {% for i in numbers %}
            <tr>
                {% for j in i %}
                    <td>{{ j }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
    </table>
</body>
img01

As we can see, it is very simple and similar to python to process lists in jinja2. We can also use different lists operations and even python functions in jinj2. 

Dictionaries

Same way we can pass dictionary to the template.
@app.route('/dictionary')
def dictionary_view():
    fruits = {'Apple': 100, 'Orange': 50, 'Banana': 20}
    return render_template('dictionary.html', fruits=fruits)
<!-- templates/dictionary.html -->

<!-- Render fruits dictionary -->
<body>
    <h1>Flask Templates - Dictionaries</h1>
    <ul>
        {% for key, value in fruits.items() %}
            <li>{{ key }} - {{ value }}</li>
        {% endfor %}
</body>
img01

Conditions

We can use different python functions in the template. Let's see an example.
@app.route('/conditions')
def functions_view():
    users = ['John', 'Jane', 'Jack']
    selected_user = 'Jane'
    return render_template('conditions.html', users=users, selected_user=selected_user)
We can use if-else statements in the template as well. We can use if, elif, and else statements in the template. We can use both comparison operator or other keywords like value in variable or value is variable
Lets check some examples that how we can use these statements.
<!-- templates/conditions.html -->
<body>
    <h1>Flask Templates - Conditions</h1>
    <ul style="width: 500px">
        {% for item in users %}
            {% if item == selected_user %} <!-- Comparing with a string variable -->
                <li style="background-color: #0BF; padding: 3px 8px; color: #444">{{ item }}</li>
            {% elif item == "Jack" %} <!-- Comparing with a string value -->
                <li style="background-color: #FAF; padding: 3px 8px; color: #444">{{ item }}</li>
            {% else %} <!-- else statement -->
                <li>{{ item }}</li>
            {% endif %}
        {% endfor %}
    </ul>
</body>
img01
In this tutorial, we have seen how to render templates in Flask. We have also seen how to pass dynamic data to the template and show in templates in different tags. We have also seen how to use different types of data types including lists, dictionaries and processed data using loops and conditions in the template.
We can perform different types of operations and modify HTML tags to our requirements in the template using Jinja2. We can use jinja2 templating for almost all of our requirements. For more details, read Jinja2 documentation.
 
For more details and tutorials on flask, check our flask home page.
https://mlhive.com/tag/flask