Python Flask Jinja Templating

Here is, pretty much, everything you need to know about Jinja templating in Python Flask.

render_template

In a Flask app, you have your main file, a static folder, and the templates folder. You can use render_template to render HTML files from inside of the templates folder.

main.py

from flask import Flask, render_template

app = Flask(__name__)


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


if __name__ == '__main__':
    app.run('0.0.0.0', 81)

Passing variables to HTML

Using the render_template function, you can pass variables to your HTML files with Jinja using the {{ <var> }} syntax.

main.py

from flask import Flask, render_template
from replit import web

...

@app.route('/')
def index():
    return render_template('index.html',
                           username=web.auth.name,
                           userid=web.auth.user_id
                          )

...

templates/index.html

<body>
    <main>
        <h1>Templating</h1>
        <!-- This is the jinja syntax to use variables passed in from render_template. -->
        <h2>Hello, {{ username }}!</h2>
        <p>Your Replit UserID is {{ userid }}.</p>
    </main>
</body>

Creating variables

Variables can be created in HTML files using the {% set <var> = <value> %} syntax.

templates/index.html

<body>
  <main>
    {% set var = "Hello, world!" %}
    <p>{{ var }}</p>
  </main>
</body>

Variable filters

You can apply filters such as length or title to variables. For example:

main.py

...

phrase = 'Hello, world!'


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

...

templates/index.html

<body>
  <main>
    <p>"{{ phrase }}" is {{ phrase | length }} characters long.</p>
  </main>
</body>

If statements

You can write if statements with Jinja too, using the {% if <condition> %} {% endif %} syntax.

main.py

from flask import Flask, render_template, request
from replit import web

admins = [
    17197014 # QwertyQwerty88
]

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html',
                           username=web.auth.name,
                           userid=web.auth.user_id
                          )

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


@app.route('/admin')
def admin():
    return render_template('admin.html',
                           admins=admins)


@app.route('/bad')
def bad():
    return "SMH, you're not an admin."


if __name__ == '__main__':
    app.run('0.0.0.0', 81)

templates/admin.html

<body>
    <!-- Jinja if statement -->
    {% if not userid %}
        <script>location.replace('/login')</script>
    {% elif userid not in admins %}
        <script>location.replace('/bad')</script>
    {% endif %}
    
    <main>
        <h1>Templating</h1>
        <!-- This is the Jinja syntax to use variables passed in from render_template. -->
        <h2>Hello, {{ username }}! You are an admin.</h2>
        <p>Your Replit UserID is {{ userid }}.</p>
    </main>
</body>

For loops

You can also write for loops with Jinja using the {% for <var> in <iterable> %} {% endfor %} syntax.

templates/admin.html

<body>
    <!-- Jinja if statement -->
    {% if not userid %}
        <script>location.replace('/login')</script>
    {% elif userid not in admins %}
        <script>location.replace('/bad')</script>
    {% endif %}
    
    <main>
        <h1>Templating</h1>
        <!-- This is the Jinja syntax to use variables passed in from render_template. -->
        <h2>Hello, {{ username }}! You are an admin.</h2>
        <p>Your Replit UserID is {{ userid }}.</p>

        <h3>All admin UserIDs</h3>
        <ul>
            <!-- Jinja for loop syntax -->
            {% for admin in admins %}
                <li>{{ admin }}</li>
            {% endfor %}
        </ul>
    </main>
</body>

Components

To use components in Flask, you need to create HTML files in the templates folder (or a subfolder inside of it) and use the {% include '<file>.html' %} Jinja syntax. Variables passed from render_template will also work in components.

templates/components/header.html

<div class="user">
    <img class="pfp" src="{{ pfp }}" alt="PFP">
    <span class="username">{{ username }}</span>
</div>

templates/index.html

<body>
    <header>{% include 'components/header.html %}</header>

    <main>
        <h1>Templating</h1>
    </main>
</body>

Base Layout

Using the {% block <name> %} {% endblock %} and {% extend '<file>.html' %} syntax, you can create a base file for your other files to follow.

templates/base.html

<body>
    <header>
        {% block header %}{% endblock %}
    </header>

    <main>
        <h1>Templating</h1>
        {% block content %}{% endblock %}
    </main>
</body>

templates/index.html

{% extends 'base.html' %}

{% block title %}Home{% endblock %}

{% block header %}{% include 'components/header.html' %}{% endblock %}

{% block content %}
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
{% endblock %}

You can also take a look at the Flask Documentation on Templates:

https://flask.palletsprojects.com/en/2.3.x/tutorial/templates/

Or the Jinja documentation:

https://jinja.palletsprojects.com/en/3.1.x/

Or my example Repl:

https://replit.com/@QwertyQwerty88/Templating

2 Likes

Oooh Jinja!

1 Like

oh @gautam your blog was moved here? I was wondering what happened to it

uhh why can’t I edit topic

1 Like