Flask模板system

LearningFlask Jinja2模板引擎, 模板语法, 模板inheritance, filter器 and 宏 - core concepts

1. Jinja2模板引擎

FlaskusingJinja2serving as默认 模板引擎. Jinja2 is a functions强 big 模板引擎, support模板inheritance, 宏, filter器etc.advanced features.

1.1 模板Table of Contents

默认circumstances under , Flask会 in applicationTable of Contents under templatesTable of Contentsinfind模板file. 可以through以 under 方式指定模板Table of Contents:

app = Flask(__name__, template_folder='templates')

1.2 渲染模板

usingrender_template()function可以渲染模板:

from flask import render_template

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

2. 模板语法

Jinja2模板using双 big 括号{{ }}表示variable, using big 括号百分号{% %}表示控制structure.

2.1 variable

in 模板inusing双 big 括号{{ variable }}可以输出variable值:

<h1>Hello, {{ name }}!</h1>

2.2 控制structure

2.2.1 if语句

{% if name %}
    <h1>Hello, {{ name }}!</h1>
{% else %}
    <h1>Hello, Guest!</h1>
{% endif %}

2.2.2 for循环

<ul>
    {% for item in items %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

2.2.3 for循环in 特殊variable

<ul>
    {% for item in items %}
        <li>
            {{ loop.index }}. {{ item }}
            {% if loop.first %} (First){% endif %}
            {% if loop.last %} (Last){% endif %}
        </li>
    {% endfor %}
</ul>

常用 循环variable:

  • loop.index: 当 before 循环 index ( from 1开始)
  • loop.index0: 当 before 循环 index ( from 0开始)
  • loop.first: is 否 is 第一个元素
  • loop.last: is 否 is 最 after 一个元素
  • loop.length: 序列 long 度

2.2.4 宏

宏class似于function, 可以复用HTMLcode:

{% macro input(name, value='', type='text', size=20) %}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}" size="{{ size }}">
{% endmacro %}

<form>
    {{ input('username') }}
    {{ input('password', type='password') }}
    {{ input('submit', value='Submit', type='submit') }}
</form>

3. 模板inheritance

模板inheritance允许我们creation一个Basics模板, 然 after in 子模板ininheritance并scale它. 这 has 助于保持模板 consistency and reducing重复code.

3.1 creationBasics模板

creation一个Basics模板base.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}My Website{% endblock %}</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
    <header>
        <h1>{% block header %}My Website{% endblock %}</h1>
    </header>
    
    <nav>
        <ul>
            <li><a href="{{ url_for('index') }}">Home</a></li>
            <li><a href="{{ url_for('about') }}">About</a></li>
            <li><a href="{{ url_for('contact') }}">Contact</a></li>
        </ul>
    </nav>
    
    <main>
        {% block content %}{% endblock %}
    </main>
    
    <footer>
        <p>© 2025 My Website</p>
    </footer>
</body>
</html>

3.2 creation子模板

creation一个子模板index.html, inheritance自base.html:

{% extends "base.html" %}

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

{% block header %}Welcome to My Website{% endblock %}

{% block content %}
    <h2>Home Page</h2>
    <p>This is the home page of my website.</p>
    <p>Hello, {{ name }}!</p>
{% endblock %}

3.3 块 嵌套 and 覆盖

子模板可以覆盖父模板in 块, 也可以 in 块in调用父模板 in 容:

{% block content %}
    {{ super() }}  {# 调用父模板 content块 in 容 #}
    <p>This is additional content from the child template.</p>
{% endblock %}

4. filter器

filter器用于modifyvariable 值. using管道符|可以applicationfilter器:

{{ variable|filter_name }}

4.1 常用filter器

filter器 describes example
upper 转换 for big 写 {{ 'hello'|upper }}HELLO
lower 转换 for small 写 {{ 'HELLO'|lower }}hello
capitalize 首字母 big 写, 其余 small 写 {{ 'hello world'|capitalize }}Hello world
title 每个单词首字母 big 写 {{ 'hello world'|title }}Hello World
trim 去除首尾空格 {{ ' hello '|trim }}hello
striptags 去除HTMLtag {{ '<h1>hello</h1>'|striptags }}hello
length 返回 long 度 {{ 'hello'|length }}5
join 连接list {{ ['a', 'b', 'c']|join(', ') }}a, b, c
default 设置默认值 {{ none_value|default('default') }}default
date format日期 {{ date|date('Y-m-d') }}2023-01-01

4.2 链式filter器

可以链式using many 个filter器:

{{ '  hello world  '|trim|title }}

输出: Hello World

5. 宏

宏 is a可复用 模板片段, class似于function.

5.1 定义宏

可以 in 模板in直接定义宏:

{% macro render_item(item) %}
    <div class="item">
        <h3>{{ item.title }}</h3>
        <p>{{ item.description }}</p>
    </div>
{% endmacro %}

5.2 using宏

in 模板inusing宏:

{% for item in items %}
    {{ render_item(item) }}
{% endfor %}

5.3 import宏

可以将宏定义 in 单独 filein, 然 after in other模板inimport:

creationmacros.htmlfile:

{% macro render_item(item) %}
    <div class="item">
        <h3>{{ item.title }}</h3>
        <p>{{ item.description }}</p>
    </div>
{% endmacro %}

{% macro render_button(text, type='button') %}
    <button type="{{ type }}">{{ text }}</button>
{% endmacro %}

in other模板inimport并using宏:

{% import 'macros.html' as macros %}

{{ macros.render_item(item) }}
{{ macros.render_button('Submit', 'submit') }}

6. on under 文processing器

on under 文processing器 is a function, 用于向所 has 模板添加variable.

6.1 定义 on under 文processing器

@app.context_processor
def inject_user():
    user = {'name': 'John', 'age': 30}
    return dict(user=user)

@app.context_processor
def inject_constants():
    return {
        'APP_NAME': 'My Flask App',
        'APP_VERSION': '1.0.0'
    }

6.2 in 模板inusing on under 文variable

<h1>{{ APP_NAME }}</h1>
<p>Version: {{ APP_VERSION }}</p>
<p>User: {{ user.name }}, Age: {{ user.age }}</p>

7. 模板in URL构建

in 模板inusingurl_for()function可以构建URL:

<a href="{{ url_for('index') }}">Home</a>
<a href="{{ url_for('user_profile', username='john') }}">John's Profile</a>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

8. 模板in 静态file

Flask默认 in staticTable of Contentsinfind静态file. usingurl_for('static', filename='filename')可以构建静态file URL.

8.1 引用CSSfile

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

8.2 引用JavaScriptfile

<script src="{{ url_for('static', filename='script.js') }}"></script>

8.3 引用graph片

<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">

9. 模板 advanced features

9.1 模板 自动转义

默认circumstances under , Jinja2会自动转义HTML in 容, 防止XSS攻击. 可以using|safefilter器关闭自动转义:

{{ html_content|safe }}

9.2 模板 package含

using{% include %}可以 in 模板inpackage含other模板:

{% include 'header.html' %}

<main>
    <h2>Content</h2>
    <p>This is the main content.</p>
</main>

{% include 'footer.html' %}

9.3 模板 宏 and inheritance结合

可以将宏定义 in Basics模板in, 然 after in 子模板inusing:

<!-- base.html -->
{% macro render_menu(items) %}
    <ul class="menu">
        {% for item in items %}
            <li><a href="{{ item.url }}">{{ item.text }}</a></li>
        {% endfor %}
    </ul>
{% endmacro %}

<!-- index.html -->
{% extends 'base.html' %}

{% block content %}
    {{ render_menu([
        { 'text': 'Home', 'url': url_for('index') },
        { 'text': 'About', 'url': url_for('about') },
        { 'text': 'Contact', 'url': url_for('contact') }
    ]) }}
    
    <h2>Home Page</h2>
{% endblock %}

10. 模板 debug

10.1 usingdumpfilter器

using|dumpfilter器可以查看variable 详细information:

{{ variable|dump }}

10.2 usingdebug语句

using{% debug %}可以 in 模板in输出debuginformation:

{% debug %}

练习 1: creationBasics模板 and 子模板

  1. creation一个Basics模板base.html, package含头部, 导航栏, 主要 in 容区域 and 页脚
  2. creation一个子模板index.html, inheritance自base.html, 并添加首页 in 容
  3. creation一个子模板about.html, inheritance自base.html, 并添加关于页面 in 容
  4. creation相应 routingfunction, 渲染这些模板
  5. test页面 is 否正常显示

练习 2: using模板variable and 控制structure

  1. creation一个routingfunction, 传递一个list and 一个dictionary to 模板
  2. in 模板inusingfor循环遍历list, 并显示每个元素
  3. in 模板inusingif语句根据条件显示不同 in 容
  4. usingfilter器format输出 in 容
  5. test页面 is 否正常显示

练习 3: creation and using宏

  1. creation一个宏filemacros.html, 定义一个渲染userinformation 宏
  2. in 模板inimport并using这个宏
  3. creation many 个userdata, using宏渲染每个userinformation
  4. test页面 is 否正常显示