- Flask · PyPI
- Primer on Jinja Templating – Real Python
- Welcome to Flask — Flask Documentation (2.3.x) (palletsprojects.com)
- Tutorial — Flask Documentation (2.3.x) (palletsprojects.com)
Installing
$ pip install -U Flask
A Simple Example
# save this as app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello, World!"
or
# app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello, World!"
if __name__ == "__main__":
app.run(debug=True)
$ flask run * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Add a Base Template
{# templates/base.html #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<h1>Welcome to {{ title }}!</h1>
</body>
</html>
# app.py
from flask import Flask
from flask import render_template
app = Flask(__name__)
@app.route("/")
def home():
return render_template("base.html", title="Jinja and Flask")
if __name__ == "__main__":
app.run(debug=True)

Add Another Page
{# templates/results.html #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ test_name }} {{ title }}</h1>
<ul>
{% for student in students %}
<li>
{% if student.score > 80 %}?{% else %}?{% endif %}
<em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
</li>
{% endfor %}
</ul>
</body>
</html>
# app.py
from flask import Flask
from flask import render_template
app = Flask(__name__)
@app.route("/")
def home():
return render_template("base.html", title="Jinja and Flask")
max_score = 100
test_name = "Python Challenge"
students = [
{"name": "Sandrine", "score": 100},
{"name": "Gergeley", "score": 87},
{"name": "Frieda", "score": 92},
{"name": "Fritz", "score": 40},
{"name": "Sirius", "score": 75},
]
@app.route("/results")
def results():
context = {
"title": "Results",
"students": students,
"test_name": test_name,
"max_score": max_score,
}
return render_template("results.html", **context)
if __name__ == "__main__":
app.run(debug=True)

Nest Your Templates
Adjust Your Base Template
{# templates/base.html #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{% block title %}{{ title }}{% endblock title %}</title>
</head>
<body>
{% block content %}
<h1>Welcome to {{ title }}!</h1>
{% endblock content %}
</body>
</html>
Extend Child Templates
{# templates/results.html #}
{% extends "base.html" %}
{% block content %}
<h1>{{ test_name }} {{ title }}</h1>
<ul>
{% for student in students %}
<li>
{% if student.score > 80 %}?{% else %}?{% endif %}
<em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
</li>
{% endfor %}
</ul>
{% endblock content %}
Include a Navigation Menu
{# templates/_navigation.html #}
<nav>
{% for menu_item in ["home", "results"] %}
<a href="{{ url_for(menu_item) }}">{{ menu_item }}</a>
{% endfor %}
</nav>
{# templates/base.html #}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{% block title %}{{ title }}{% endblock title %}</title>
</head>
<body>
<header>
{% include "_navigation.html" %}
</header>
{% block content %}
<h1>Welcome to {{ title }}!</h1>
{% endblock content %}
</body>
</html>


Apply Filters
Adjust Your Menu Items
แสดง link เป็น ตัวพิมพ์ใหญ่ด้วย filter upper
{# templates/_navigation.html #}
<nav>
{% for menu_item in ["home", "results"] %}
<a href="{{ url_for(menu_item) }}">{{ menu_item|upper }}</a>
{% endfor %}
</nav>

Sort Your Results List
เรียกตาม name ด้วย filter sort
{# templates/results.html #}
{% extends "base.html" %}
{% block content %}
<h1>{{ test_name }} {{ title }}</h1>
<ul>
{% for student in students|sort(attribute="name") %}
<li>
{% if student.score > 80 %}?{% else %}?{% endif %}
<em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
</li>
{% endfor %}
</ul>
{% endblock content %}

You used Jinja’s sort filter to sort the results of your students by their names. If you had students with the same name, then you could chain the filters:
{% for student in students|sort(attribute="score", reverse=true)
|sort(attribute="name") %}
{# ... #}
{% endfor %}

Include Macros
Implement a Dark Mode
{# templates/macros.html #}
{% macro light_or_dark_mode(element) %}
{% if request.args.get('mode') == "dark" %}
<a href="{{ request.path }}">Switch to Light Mode</a>
<style>
{{ element }} {
background-color: #212F3C;
color: #FFFFF0;
}
{{ element }} a {
color: #00BFFF !important;
}
</style>
{% else %}
<a href="{{ request.path }}?mode=dark">Switch to Dark Mode</a>
{% endif %}
{% endmacro %}
{# templates/base.html #}
{% import "macros.html" as macros %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>{% block title %}{{ title }}{% endblock title %}</title>
</head>
<body>
<header>
{% include "_navigation.html" %}
</header>
{% block content %}
<h1>Welcome to {{ title }}!</h1>
{% endblock content %}
<footer>
{{ macros.light_or_dark_mode("body") }}
</footer>
</body>
</html>


Highlight Your Best Student
{# templates/results.html #}
{% extends "base.html" %}
{% block content %}
<h1>{{ test_name }} {{ title }}</h1>
<ul>
{% for student in students|sort(attribute="name") %}
<li>
{{ macros.add_badge(student, students) }}
<em>{{ student.name }}:</em> {{ student.score }}/{{ max_score }}
</li>
{% endfor %}
</ul>
{% endblock content %}
{# templates/macros.html #}
{% macro light_or_dark_mode(element) %}
{% if request.args.get('mode') == "dark" %}
<a href="{{ request.path }}">Switch to Light Mode</a>
<style>
{{ element }} {
background-color: #212F3C;
color: #FFFFF0;
}
{{ element }} a {
color: #00BFFF !important;
}
</style>
{% else %}
<a href="{{ request.path }}?mode=dark">Switch to Dark Mode</a>
{% endif %}
{% endmacro %}
{% macro add_badge(student, students) %}
{% set high_score = students|map(attribute="score")|max %}
{% if student.score == high_score %}
⭐️
{% elif student.score > 80 %}
?
{% else %}
?
{% endif %}
{% endmacro %}

Mark the Current Page
{# templates/macros.html #}
{# ... #}
{% macro nav_link(menu_item) %}
{% set mode = "?mode=dark" if request.args.get("mode") == "dark" else "" %}
<a href="{{ url_for(menu_item) }}{{ mode }}">{{ menu_item|upper }}</a>
{% if request.endpoint == menu_item %}
←
{% endif %}
{% endmacro %}
{# templates/_navigation.html #}
<nav>
{% for menu_item in ["home", "results"] %}
{{ macros.nav_link(menu_item) }}
{% endfor %}
</nav>

