模板¶
Flask利用Jinja2作为其模板引擎。显然,您可以自由地使用不同的模板引擎,但是您仍然需要安装Jinja2来运行Flask本身。这个要求对于启用丰富的扩展是必要的。扩展可以依赖于Jinja2的存在。
本节只简单介绍了如何将金贾2集成到烧瓶中。如果您想了解模板引擎语法本身的信息,请到官员那里。 Jinja2 Template Documentation 更多信息。
Jinja设置¶
Jinja2 默认配置如下:
当使用 render_template() 时,扩展名为 .html 、 .htm 、 .xml 和 .xhtml 的模板中开启自动转义。
当使用 render_template_string() 时,字符串开启 自动转义
模板可以选择使用
{{% autoescape %}}
标签来手动设置是否转义。Flask 在Jinja2 环境中加入一些全局函数和辅助对象,以增强模板的功能。
标准环境¶
默认情况下,以下全局变量可以在jinja2模板中使用:
-
config
当前配置对象(
flask.config
)Changelog
在 0.10 版更改: 现在,即使在导入的模板中,它也始终可用。
0.6 新版功能.
-
request
当前请求对象(
flask.request
)如果模板在没有活动请求环境的情况下渲染,则此变量不可用。
-
session
当前会话对象(
flask.session
)如果模板在没有活动请求环境的情况下渲染,则此变量不可用。
-
g
全局变量的请求绑定对象(
flask.g
)如果模板在没有活动请求环境的情况下渲染,则此变量不可用。
-
url_for
() func:`flask.url_for`函数 。
-
get_flashed_messages
()
Jinja 语境行为
这些被添加到变量的语境中的变量,它们不是全局变量。不同之处在于,默认情况下,它们不会显示在导入模板的环境中。这部分是由于性能方面的原因,同时也考虑让代码更有条理。
这对你来说意味着什么?如果有要导入的宏,则需要访问请求对象,那么你有两种选择:
显式地把请求或都该请求有用的属性作为参数传递给宏。
导入“with context”宏。
导入方式如下:
{% from '_helpers.html' import my_macro with context %}
标准过滤器¶
除Jinja2自身提供的过滤器外,Flask还提供以下Jinja2过滤器:
-
tojson
() 此函数将给定对象转换为JSON格式。例如,如果你要动态生成JavaScript,这将非常有用。
<script type=text/javascript> doSomethingWith({{ user.username|tojson }}); </script>
在 single-quoted HTML属性中使用JSON也是很安全的:
<button onclick='doSomethingWith({{ user.username|tojson }})'> Click me </button>
注意,在 script 标记内部不能转义,因此在 Flask 0.10 之前的版本中, 如果要在 script 标记内部使用这个函数必须用 |safe 关闭转义:
控制自动转义¶
自动转义是自动转义特殊字符的概念。HTML(或XML,因此XHTML)意义上的特殊字符是 &
, >
, <
, "
以及 '
. 因为这些字符本身在文档中具有特定的含义,所以如果要将它们用于文本,则必须将它们替换为所谓的“实体”。不这样做不仅会导致用户因为无法在文本中使用这些字符而感到沮丧,而且还会导致安全问题。(见 跨站点脚本攻击(XSS) )
但是,有时需要禁用模板中的自动转义。如果你想要显式地将HTML植入页面,例如,如果页面来自一个生成安全HTML的系统,比如标记为HTML的转换器,那么就可能出现这种情况。
有三种方法可以控制自动转义:
在 Python 代码中,可以在把 HTML 字符串传递给模板之前,用 Markup 对象封装。这通常是推荐的方法。
在模板内,使用
|safe
筛选以将字符串显式标记为安全HTML({{{{ myvariable|safe }}}}
)临时完全禁用自动转义系统。
要在模板中禁用自动转义系统,可以使用 {{% autoescape %}}
{% autoescape false %}
<p>autoescaping is disabled here
<p>{{ will_not_be_escaped }}
{% endautoescape %}
无论何时,都务必格外小心这里的变量。
注册过滤器¶
如果您想在Jinja2注册自己的过滤器,有两种方法可以做到这一点。要么手动把它们放进 jinja_env
或使用 template_filter()
装饰者。
以下两个示例的工作原理相同,并且都会反转一个对象:
@app.template_filter('reverse')
def reverse_filter(s):
return s[::-1]
def reverse_filter(s):
return s[::-1]
app.jinja_env.filters['reverse'] = reverse_filter
对于decorator,如果要使用函数名作为筛选器的名称,则参数是可选的。注册后,你可以使用模板中的过滤器,方法与Jinja2的内置过滤器相同,例如,假设在环境中你有一个 名为 mylist 的 Pyhton 列表:
{% for x in mylist | reverse %}
{% endfor %}
环境处理器¶
为了将新变量自动注入模板的环境中,环境处理器在模板被渲染前运行,因此可以把新的变量自动引入模板环境中。它是一个函数,返回一个字典的函数。这个字典的键值最终将传入应用中所有模板的环境中:
@app.context_processor
def inject_user():
return dict(user=g.user)
上例中的环境处理器创建了一个值为 g.user 的 user 变量,并把这个变量加入 了模板环境中。这个例子只是用于说明工作原理,不是非常有用,因为在模板中, g 总是存在的。
变量不限于值;环境处理器也可以使函数对模板可用(因为Python允许传递函数)::
@app.context_processor
def utility_processor():
def format_price(amount, currency="€"):
return f"{amount:.2f}{currency}"
return dict(format_price=format_price)
上面的环境处理器使 format_price 可用于所有模板的函数:
{{ format_price(0.33) }}
你还可以把 format_price 创建为一个模板过滤器(参见 注册过滤器 ),这里只是演示如何在一个环境处理器中传递函数。