Jinja2 是一个现代的、设计优雅的 Python 模板引擎。它被广泛用于生成动态网页内容,但它也可以用于其他文本生成任务。本文将详细介绍如何在使用 Jinja2 库,并通过丰富的示例演示其强大的功能。
安装 Jinja2
首先,我们需要安装 Jinja2。你可以使用 pip 进行安装:
pip install jinja2
基本用法
1. 创建模板
Jinja2 的核心概念是模板。模板是包含特殊语法的文本文件,用于生成最终的输出。下面是一个简单的 Jinja2 模板示例:
Hello, {{ name }}!
2. 渲染模板
我们可以使用 Environment 和 Template 类来渲染模板。下面是一个简单的示例:
from jinja2 import Template
template = Template('Hello, {{ name }}!')
rendered = template.render(name='John')
print(rendered) # 输出:Hello, John!
模板语法
1. 变量
可以在模板中使用双大括号 {{ }}
包围变量来进行渲染:
My name is {{ name }} and I am {{ age }} years old.
template = Template('My name is {{ name }} and I am {{ age }} years old.')
rendered = template.render(name='Alice', age=30)
print(rendered) # 输出:My name is Alice and I am 30 years old.
2. 控制结构
条件语句
Jinja2 支持使用 {% %}
包围的控制结构,例如条件语句:
{% if user %}
Hello, {{ user }}!
{% else %}
Hello, Stranger!
{% endif %}
template = Template('''
{% if user %}
Hello, {{ user }}!
{% else %}
Hello, Stranger!
{% endif %}
''')
rendered = template.render(user='Alice')
print(rendered) # 输出:Hello, Alice!
循环
你可以在模板中使用 for
循环:
- Items:
{% for item in items %}
- {{ item }}
{% endfor %}
template = Template('''
- Items:
{% for item in items %}
- {{ item }}
{% endfor %}
''')
rendered = template.render(items=['Apple', 'Banana', 'Cherry'])
print(rendered)
输出
Items:
- Apple
- Banana
- Cherry
3. 宏
宏允许你定义可重用的代码片段:
{% macro input(name, value='', type='text') %}
`{{ name }}: <input type="{{ type }}" value="{{ value }}">`
{% endmacro %}
{{ input('username') }}
template = Template('''
{% macro input(name, value='', type='text') %}
`{{ name }}: <input type="{{ type }}" value="{{ value }}">`
{% endmacro %}
{{ input('username') }}
''')
rendered = template.render()
print(rendered)
输出
`username: <input type="text" value="">`
这个宏有三个参数:
name: 用于指定 <input> 元素的 name 属性。
value: 用于指定 <input> 元素的 value 属性,默认值为空字符串。
type: 用于指定 <input> 元素的 type 属性,默认值为 'text'。
4. 过滤器
过滤器用于修改变量的输出。你可以在变量后使用管道符 |
和过滤器名称:
{{ "hello world" | capitalize }}
template = Template('{{ "hello world" | capitalize }}')
rendered = template.render()
print(rendered) # 输出:Hello world
常见的 Jinja2 过滤器
- safe:将变量标记为安全的 HTML,不会被自动转义。
示例:{{ "<div>Hello</div>"|safe }}
- escape:将变量中的 HTML 特殊字符转义。
示例:{{ "<div>Hello</div>"|escape }} 会输出 <div>Hello</div>
- capitalize:将字符串的首字母大写。
示例:{{ "hello world"|capitalize }} 会输出 Hello world
- lower:将字符串转换为小写。
示例:{{ "HELLO WORLD"|lower }} 会输出 hello world
- upper:将字符串转换为大写。
示例:{{ "hello world"|upper }} 会输出 HELLO WORLD
- title:将字符串中的每个单词的首字母大写。
示例:{{ "hello world"|title }} 会输出 Hello World
- trim:移除字符串首尾的空白字符。
示例:{{ " hello world "|trim }} 会输出 hello world
- striptags:移除字符串中的所有 HTML 标签。
示例:{{ "<div>Hello</div>"|striptags }} 会输出 Hello
- replace:将字符串中的子字符串替换为指定的字符串。
示例:{{ "hello world"|replace("world", "Jinja2") }} 会输出 hello Jinja2
- length:返回变量的长度。
示例:{{ "hello world"|length }} 会输出 11
- default:当变量为 None 或为空时,使用默认值。
示例:{{ none_variable|default('default_value') }}
- join:将列表中的元素连接成一个字符串,使用指定的分隔符。
示例:{{ [1, 2, 3]|join(', ') }} 会输出 1, 2, 3
- sort:对列表进行排序。
示例:{{ [3, 1, 2]|sort }} 会输出 [1, 2, 3]
- unique:去除列表中的重复元素。
示例:{{ [1, 2, 2, 3]|unique }} 会输出 [1, 2, 3]
- reverse:反转列表或字符串。
示例:{{ "hello world"|reverse }} 会输出 dlrow olleh
- sum:返回列表中所有元素的和。
示例:{{ [1, 2, 3]|sum }} 会输出 6
- default:当变量为 None 或空时,使用指定的默认值。
示例:{{ variable|default('default_value') }}
- date:将日期格式化为指定的格式。
示例:{{ some_date|date("Y-m-d") }}
5. 模板继承
模板继承允许你定义一个基本的模板,然后从这个基本模板继承以创建新的模板:
base.md
# {{ title }}
{% block content %}{% endblock %}
index.md
{% extends "base.md" %}
{% block title %}Home Page{% endblock %}
{% block content %}
## Welcome
This is the home page.
{% endblock %}
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('templates'))
template = env.get_template('index.md')
rendered = template.render()
print(rendered)
输出:
# Home Page
## Welcome
This is the home page.
使用环境变量
你可以使用 Environment 类来配置 Jinja2 的环境,包括加载模板的路径、自动转义等。
from jinja2 import Environment, FileSystemLoader, select_autoescape
env = Environment(
loader=FileSystemLoader('templates'),
autoescape=select_autoescape(['md'])
)
template = env.get_template('example.md')
rendered = template.render(data='Example Data')
print(rendered)
自定义过滤器和测试
1. 自定义过滤器
你可以定义自己的过滤器:
def reverse_string(s):
return s[::-1]
env = Environment()
env.filters['reverse'] = reverse_string
template = env.from_string('{{ "hello" | reverse }}')
rendered = template.render()
print(rendered) # 输出:olleh
2. 自定义测试
你可以定义自己的测试:
def is_even(n):
return n % 2 == 0
env = Environment()
env.tests['even'] = is_even
template = env.from_string('''
{% if 4 is even %}
4 is even
{% endif %}
''')
rendered = template.render()
print(rendered) # 输出:4 is even
总结
Jinja2 是一个功能强大的模板引擎,可以在多种场景下使用,包括但不限于 web 开发。它提供了丰富的模板语法、控制结构、宏、过滤器和模板继承功能,极大地提高了模板生成的灵活性和可重用性。通过学习和使用 Jinja2,可以轻松地生成各种文本输出,实现更高效的代码编写和维护。