在Web开发中,我们常常需要将后端的数据(如用户信息、商品列表、文章内容等)展示到前端页面上。如果手动拼接HTML和数据,会变得非常繁琐且容易出错。而模板引擎(Template Engine)正是解决这个问题的工具——它允许我们在HTML中嵌入动态内容,让后端数据“注入”到页面中,生成最终的网页。

一、什么是Jinja2和模板引擎?

模板引擎的核心作用是将后端数据与HTML模板结合,生成可直接展示给用户的网页。它就像一个“模板工具”,让开发者专注于数据逻辑和页面结构的分离,而不是重复编写静态HTML和动态数据拼接的代码。

Jinja2 是Flask框架的默认模板引擎,由Python实现,语法简洁且功能强大。它支持变量替换、条件判断、循环、过滤器等功能,能高效地处理动态数据渲染。

二、在Flask中使用Jinja2的基本流程

要在Flask中使用Jinja2,只需遵循以下步骤:

1. 准备环境:安装Flask

首先确保已安装Flask。如果未安装,可通过pip安装:

pip install flask

2. 创建Flask应用与路由

在项目根目录下创建app.py,定义一个简单的Flask应用和路由,用于提供数据和渲染模板:

from flask import Flask, render_template  # 导入Flask和模板渲染工具

app = Flask(__name__)  # 创建Flask应用实例

# 定义路由,访问首页时执行index函数
@app.route('/')
def index():
    # 准备后端数据(可以是字典、列表、对象等)
    user_info = {
        'name': '小明',
        'age': 20,
        'hobbies': ['篮球', '编程', '阅读'],  # 爱好列表
        'is_student': True,  # 是否是学生
        'posts': [  # 文章列表
            {'title': 'Python入门教程', 'author': '小明', 'date': '2023-01-15'},
            {'title': 'Flask实战', 'author': '小明', 'date': '2023-02-20'}
        ]
    }
    # 渲染模板并返回数据
    return render_template('index.html', **user_info)  # **user_info将字典拆分为参数

if __name__ == '__main__':
    app.run(debug=True)  # 调试模式运行

3. 创建模板文件

Flask默认会在项目根目录下的templates文件夹中寻找模板文件(若不存在需手动创建)。因此,需在项目根目录新建templates文件夹,并在其中创建index.html作为模板文件:

项目结构:
your_project/
├── app.py          # Flask应用代码
└── templates/      # 模板文件夹
    └── index.html  # 模板文件

4. 在模板中使用Jinja2语法

templates/index.html中,使用Jinja2语法嵌入动态数据:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{{ name }}的个人主页</title>
</head>
<body>
    <h1>欢迎访问{{ name }}的主页!</h1>

    <!-- 变量替换:直接显示后端传递的name -->
    <p>年龄:{{ age }}岁</p>

    <!-- 条件判断:根据年龄判断是否成年 -->
    {% if age >= 18 %}
        <p>状态:成年人</p>
    {% else %}
        <p>状态:未成年人</p>
    {% endif %}

    <!-- 循环遍历:展示爱好列表 -->
    <h2>我的爱好</h2>
    <ul>
        {% for hobby in hobbies %}
            <li>{{ loop.index }}. {{ hobby }}</li>  <!-- loop.index显示序号 -->
        {% endfor %}
    </ul>

    <!-- 条件+循环:展示文章列表 -->
    <h2>我的文章</h2>
    <table border="1">
        <tr>
            <th>标题</th>
            <th>作者</th>
            <th>发布日期</th>
        </tr>
        {% for post in posts %}
            <tr>
                <td>{{ post.title }}</td>
                <td>{{ post.author }}</td>
                <td>{{ post.date }}</td>
            </tr>
        {% endfor %}
    </table>

    <!-- 嵌套对象数据:判断是否为学生 -->
    {% if is_student %}
        <p>身份:在校学生</p>
    {% else %}
        <p>身份:社会人士</p>
    {% endif %}
</body>
</html>

5. 运行应用并测试

启动app.py

python app.py

访问http://127.0.0.1:5000,即可看到动态渲染的页面,包含小明的信息、爱好列表和文章列表。

三、Jinja2核心语法速览

上面的示例中已经用到了Jinja2的基本语法,以下是最常用的核心功能:

1. 变量替换

{{ 变量名 }}在模板中嵌入后端传递的变量。例如:

<p>用户名:{{ user.name }}</p>  <!-- 后端传递user字典 -->
<p>价格:{{ product.price }}</p>  <!-- 后端传递product对象 -->

2. 条件判断(if-else)

{% if ... %}{% else %}{% elif %}实现条件逻辑。例如:

{% if is_logged_in %}
    <p>欢迎回来!</p>
{% else %}
    <p>请先登录</p>
{% endif %}

3. 循环遍历(for)

{% for ... %}遍历列表、字典或其他可迭代对象。常用变量:
- loop.index:当前循环的序号(从1开始)
- loop.first:是否为循环的第一个元素(布尔值)
- loop.last:是否为循环的最后一个元素(布尔值)

例如遍历爱好列表:

{% for hobby in hobbies %}
    <li>{{ hobby }}</li>
{% endfor %}

4. 过滤器(Filter)

Jinja2支持过滤器对变量进行处理(如格式化、转换等),用|连接过滤器名。例如:
- {{ name|upper }}:将字符串转为大写
- {{ date|format('%Y-%m-%d') }}:格式化日期(需结合Python的datetime)
- {{ text|truncate(20) }}:截断长文本为20个字符

示例:

<p>标题:{{ post.title|truncate(15) }}</p>  <!-- 截断标题长度 -->

四、进阶技巧:模板继承

当项目中有多个页面(如首页、文章页、个人中心)时,重复编写相同的HTML结构(如导航栏、页脚)会很麻烦。Jinja2支持模板继承,通过base.html作为基础模板,其他页面“继承”并扩展它。

1. 创建基础模板(base.html)

templates文件夹中创建base.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
    <nav>
        <a href="/">首页</a> | <a href="/about">关于</a>
    </nav>
    <main>
        {% block content %}{% endblock %}  <!-- 内容区块,子模板可覆盖 -->
    </main>
    <footer>© 2023 我的网站</footer>
</body>
</html>

2. 子模板继承(index.html)

index.html中通过{% extends "base.html" %}继承基础模板,并覆盖block

{% extends "base.html" %}  <!-- 继承base.html -->

{% block title %}小明的主页{% endblock %}  <!-- 覆盖标题区块 -->

{% block content %}  <!-- 覆盖内容区块 -->
    <h1>欢迎来到小明的主页!</h1>
    <p>这是继承base.html后的内容。</p>
{% endblock %}

五、总结

Jinja2模板引擎让Flask后端数据的前端渲染变得简单直观。通过变量替换、条件判断、循环等语法,我们可以轻松实现动态页面;而模板继承则进一步提高了代码复用性,让项目结构更清晰。

掌握Jinja2后,你可以继续探索更多高级功能,如宏(Macro,复用代码片段)、测试过滤器、自定义函数等。随着实践的深入,你会发现模板引擎是Web开发中连接数据与用户界面的核心工具。

提示:初学者建议先从简单示例(如本文的个人主页)入手,逐步尝试复杂场景(如数据库查询结果渲染、表单数据动态回显),再深入学习模板继承和高级语法。

小夜