So you may have seen this post:
Which goes over the basics of Flask. There is a little bit about templating, but I’d like to go into a bit more detail about it.
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.
Code
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.
Code
main.py
from flask import Flask, render_template, request
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html',
username=request.headers['X-Replit-User-Name'],
userid=request.headers['X-Replit-User-Id']
)
if __name__ == '__main__':
app.run('0.0.0.0', 81)
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Templating</title>
</head>
<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>
</html>
If statements
You can write if statements with Jinja too, using the {% if <condition> %}
{% endif %}
syntax.
Code
main.py
from flask import Flask, render_template, request
admins = [
17197014 # QwertyQwerty88
]
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html',
username=request.headers['X-Replit-User-Name'],
userid=request.headers['X-Replit-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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Templating</title>
</head>
<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>
</html>
For loops
You can also write for loops with Jinja using the {% for <var> in <iterable> %}
{% endfor %}
syntax.
Code
templates/admin.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Templating</title>
</head>
<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>
</html>
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.
Code
templates/components/header.html
<div class="user">
<img class="pfp" src="{{ pfp }}" alt="PFP">
<span class="username">{{ username }}</span>
</div>
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Templating</title>
</head>
<body>
<header>{% include 'components/header.html %}</header>
<main>
<h1>Templating</h1>
</main>
</body>
</html>
Base Layout
Using the {% block <name> %}
{% endblock %}
and {% extend '<file>.html' %}
syntax, you can create a base file for your other files to follow.
Code
templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{% block title %} | Templating</title>
</head>
<body>
<header>
{% block header %}{% endblock %}
</header>
<main>
<h1>Templating</h1>
{% block content %}{% endblock %}
</main>
</body>
</html>
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: