1. Basics of template rendering
1.1 Why you need a template engine
In web development, writing HTML code directly in Python files will cause many problems:
- The code is difficult to maintain
- Severe front and back end coupling
- Unable to reuse HTML components
- Lack of logical control
Flask has built-in Jinja2 template engine, which perfectly solves these problems.
1.2 First template rendering example
First create the project structure:
myapp/
├──
└── templates/
└──
content:
from flask import Flask, render_template app = Flask(__name__) @('/') def index(): user = {'username': 'Zhang San', 'age': 25} posts = [ {'title': 'The first article', 'content': 'Content 1'}, {'title': 'Part 2', 'content': 'Content 2'} ] return render_template('', user=user, posts=posts) if __name__ == '__main__': (debug=True)
templates/content:
<!DOCTYPE html> <html> <head> <title>{{ }}Home page</title> </head> <body> <h1>welcome, {{ }}!</h1> <p>age: {{ }}</p> <h2>Article list</h2> <ul> {% for post in posts %} <li>{{ }} - {{ }}</li> {% endfor %} </ul> </body> </html>
1.3 Template Rendering Principle
Workflow of render_template() function:
- Find the specified template file in the templates directory
- Analyze variables and logic in templates
- Pass context variables into template
- Generate the final HTML response
2. Template access object properties
2.1 Access dictionary properties
<p>username: {{ user['username'] }}</p> <p>age: {{ ('age', 18) }}</p> <!-- With default value -->
2.2 Accessing object properties
Suppose we have a User class:
class User: def __init__(self, username, email): = username = email
You can access the template like this:
<p>username: {{ }}</p> <p>Mail: {{ }}</p>
2.3 Access lists and tuples
<p>First article: {{ posts[0].title }}</p> <p>Last article: {{ posts[-1].title }}</p>
2.4 Special variable access
<p>Current time: {{ }}</p> <!-- accessFlaskConfiguration --> <p>Request method: {{ }}</p> <!-- access请求对象 --> <p>Session information: {{ ('user_id') }}</p> <p>Flash message: {{ get_flashed_messages() }}</p>
3. Use of filters
3.1 Complete collection of built-in filters
Jinja2 provides a wealth of built-in filters:
<!-- String processing --> <p>{{ "hello"|capitalize }}</p> <!-- Hello --> <p>{{ "HELLO"|lower }}</p> <!-- hello --> <p>{{ "hello world"|title }}</p> <!-- Hello World --> <p>{{ "hello"|replace("e", "a") }}</p> <!-- hallo --> <!-- List processing --> <p>{{ [1,2,3]|length }}</p> <!-- 3 --> <p>{{ [1,2,3]|first }}</p> <!-- 1 --> <p>{{ [1,2,3]|last }}</p> <!-- 3 --> <p>{{ [1,2,3]|join("|") }}</p> <!-- 1|2|3 --> <!-- Numerical processing --> <p>{{ 3.1415926|round(2) }}</p> <!-- 3.14 --> <p>{{ 1000|filesizeformat }}</p> <!-- 1000 Bytes --> <p>{{ 0.85|float }}</p> <!-- 0.85 --> <!-- Date processing --> <p>{{ user.create_time|datetimeformat }}</p> <p>{{ user.create_time|datetimeformat('%Y-%m-%d') }}</p> <!-- HTMLdeal with --> <p>{{ "<script>alert(1)</script>"|escape }}</p> <p>{{ "Markdown text"|markdown }}</p> <p>{{ ""|urlencode }}</p>
3.2 Custom filters
Register custom filters in:
@app.template_filter('reverse') def reverse_filter(s): return s[::-1] @app.template_filter('format_phone') def format_phone(phone): return f"{phone[:3]}-{phone[3:7]}-{phone[7:]}"
Used in templates:
<p>{{ "hello"|reverse }}</p> <!-- olleh --> <p>{{ "13812345678"|format_phone }}</p> <!-- 138-1234-5678 -->
Advanced Tips for Flask Template
1. Control statements
Conditional judgment
{% if < 18 %} <p>Minor users</p> {% elif > 60 %} <p>Elderly users</p> {% else %} <p>Adult user</p> {% endif %}
Loop statement
<table> <thead> <tr> <th>Serial number</th> <th>title</th> <th>content</th> </tr> </thead> <tbody> {% for post in posts %} <tr class="{{ ('odd', 'even') }}"> <td>{{ }}</td> <td>{{ }}</td> <td>{{ }}</td> </tr> {% else %} <tr> <td colspan="3">No article yet</td> </tr> {% endfor %} </tbody> </table>
Circular variable description:
- : Current number of iterations (starting from 1)
- loop.index0: Current number of iterations (starting from 0)
- : Number of reverse iterations
- : Whether it is the first iteration
- : Whether it last iteration
- : Sequence length
Macro definition (template function)
Defining macros:
{% macro render_comment(comment) %} <div class="comment"> <p>{{ }} explain:</p> <blockquote>{{ }}</blockquote> </div> {% endmacro %}
Using macros:
{{ render_comment(comment) }} <!-- Import macros from other templates --> {% from '' import render_comment %}
2. Template inheritance
Basic template()
<!DOCTYPE html> <html> <head> <title>{% block title %}Default title{% endblock %}</title> {% block head %} <link rel="stylesheet" href="{{ url_for('static', filename='') }}" rel="external nofollow" > {% endblock %} </head> <body> <div class="container"> {% block content %} <h1>Default content</h1> {% endblock %} </div> {% block footer %} <footer> <p>&copy; 2023 My App</p> </footer> {% endblock %} </body> </html>
Sub-template inheritance
{% extends "" %} {% block title %}User Home Page - {{ super() }}{% endblock %} {% block head %} {{ super() }} <style> .profile { color: blue; } </style> {% endblock %} {% block content %} <div class="profile"> <h1>{{ }}Personal profile</h1> <p>age: {{ }}</p> </div> {% endblock %} {% block footer %} <footer> <p>&copy; 2023 User Center</p> </footer> {% endblock %}
Includes other templates
<!-- Includes head --> {% include '' %} <!-- With parameters included --> {% include 'user_card.html' with user=current_user %} <!-- Ignore missing templates --> {% include '' ignore missing %}
3. Load static files
Static file organization
Standard project structure:
myapp/
├──
├── static/
│ ├── css/
│ ├── js/
│ └── images/
└── templates/
Reference static files
<!-- CSSdocument --> <link rel="stylesheet" href="{{ url_for('static', filename='css/') }}" rel="external nofollow" > <!-- JavaScriptdocument --> <script src="{{ url_for('static', filename='js/') }}"></script> <!-- picture --> <img src="{{ url_for('static', filename='images/') }}" alt="Logo"> <!-- Use cache clearance --> <link rel="stylesheet" href="{{ url_for('static', filename='css/', v=1.0) }}" rel="external nofollow" >
Static file version control
Add a version number to the configuration:
['SEND_FILE_MAX_AGE_DEFAULT'] = 3600 #1 hour cache['STATIC_VERSION'] = '1.0.0'
Used in templates:
<link rel="stylesheet" href="{{ url_for('static', filename='css/') }}?v={{ config.STATIC_VERSION }}" rel="external nofollow" >
Using CDN resources
{% if config.CDN_ENABLED %} <script src="/jquery/3.6."></script> {% else %} <script src="{{ url_for('static', filename='js/') }}"></script> {% endif %}
The above is a detailed explanation of the use of Flask templates and advanced techniques in Python. For more information about Python Flask templates, please follow my other related articles!