购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

4.5 模板环境

4.5.1 模板上下文

通过render_template传入的变量,实际上是保存到了模板的上下文中,当然Jinja2也有一些内置的上下文变量,可以通过app.context_processor来添加全局上下文。所以简单地理解上下文就是模板中可以直接使用的变量。

1. 自定义变量

变量除了通过render_template渲染外,还可以在模板中通过set语法来定义新变量。示例代码如下。

    {% set name='admin' %}

使用set赋值语句创建的变量在其之后都是有效的。如果不想让一个变量污染全局环境,可以使用with语句来创建一个内部的作用域,将set语句放到其中,这样创建的变量就只能在with代码块中才有效,示例代码如下。

    {% with %}
       {% set foo = 42 %}
       {{ foo }}
    {% endwith %}

也可以在with后面直接添加变量,如以上写法可以简写成以下形式。

    {% with foo = 42 %}
        {{ foo }}
    {% endwith %}

以上两种写法是等价的,一旦超出with代码块,就不能再使用foo这个变量了。

2. Jinja2内置全局上下文变量

Jinja2为了方便开发者,已经提前内置了一些常用的全局上下文变量,如表4-3所示。

表4-3 Jinja2内置全局上下文变量

表4-3所示的上下文变量可以在所有模板中直接使用,不需要额外传参。

3. 上下文处理器

Jinja2虽然内置了一些上下文变量,但有时候我们需要传递自定义的变量。如很多网站的导航条右上角会显示当前登录的用户名,这就需要把user变量传递到几乎所有模板中,如果通过render_template传递,则会很麻烦。这时就可以通过上下文处理器装饰器@app.context_processor来实现,示例代码如下。

    @app.context_processor
    def context_user():
        user = {"username":"admin","level": 2}
        return {"user": user}

在自定义的上下文处理器函数中,需要把变量放到字典中才能在模板中被使用。另外,上下文中的变量,除了Jinja2内置的全局上下文变量以外,其余上下文变量不能再被import导入的模板中使用,如果需要使用,则需要使用with context语法,详情请参见4.4.1节“宏和import语句”。

4.5.2 全局函数

1. 内置全局函数

为了增强Jinja2模板的逻辑功能,Jinja2内置了一些全局函数,这些函数在所有模板中都可以使用,包括被导入的模板。内置的全局函数如表4-4所示。

表4-4 Jinja2内置全局函数

此外还有3个全局类,即cycler、joiner、namespace,详细内容可参考Jinja2官方文档全局函数https://jinja.palletsprojects.com/en/3.0.x/templates/#list-of-global-functions。

除了Jinja2内置的全局函数外,Flask也提供了两个全局函数,如表4-5所示。

表4-5 Flask提供的全局函数

url_for函数可以用来构建URL和加载静态文件,构建URL与在Python脚本中的用法是一样的,示例代码如下。

    {{ url_for("book_detail",book_id=1) }}

关于url_for函数如何加载静态文件,以及get_flashed_message函数的使用,后续内容会详细讲解。

2. 自定义全局函数

如果要实现自定义的全局函数,可以通过app.template_global装饰器来实现,示例代码如下。

    @app.template_global()
    def greet(name):
        return "欢迎!%s"%name

以上自定义的全局函数可以在模板中直接使用,示例代码如下。

    <div>{{ greet("张三") }}</div>

4.5.3 Flask模板环境

在Flask中使用Jinja2,还可以使用app.jinja_env属性来配置模板。app.jinja_env是jinja2.Environment类的对象,下面讲解jinja2.Environment对象常用的属性。

1. 设置autoescape

Jinja2默认是开启了全局转义的,如果要关闭全局转义,可以通过以下代码实现。

    # 关闭全局转义
    app.jinja_env.autoescape = False
2. 添加过滤器

添加过滤器可以通过app.jinja_env.filters实现,代码如下。

    def myadd(a,b):
       return a + b
     
    app.jinja_env.filters["myadd"] = myadd
3. 添加全局对象

app.template_global()装饰器只能添加全局函数,如果需要其他Python对象,则可以通过app.jinja_env.globals实现,可以为其添加任意类型的Python对象,代码如下。

    app.jinja_env.globals["user"] = user
4. 添加测试器

添加测试器可以通过app.jinja_env.tests实现,代码如下。

    def is_admin(user):
       if user.role == "admin":
           return True
       else:
           return False
     
    app.jinja_env.tests["is_admin"] = is_admin

关于jinja2.Environment的其他属性,读者可以自行阅读其官方文档https://jinja.palletsprojects.com/en/3.0.x/api/?highlight=environment#jinja2.Environment进行了解。 Fhbcu3YYOu5khjNSCXMVFynI3s/4JiH/8Z8mpW8w9P2/uZNFCI0V3YAuszUWMq9d

点击中间区域
呼出菜单
上一章
目录
下一章
×