测试器
在Jinja2中,测试器(Test)是一些用来测试变量或者表达式,返回布尔值的特殊函数
例如,用测试器来判断一个变量或表达式是否是一个数字
{% if age is number %} {{ age*365 }} {% else %} 数字无效 {% endif %}
内置测试器
Jinja2内置了许多测试器,其中比较常用的有
- calable(obj) 判断对象是否可以被调用
- defined(value) 判断变量是否已经定义
- undefiend(value) 判断变量是否未定义
- none(value) 判断变量是否为none
- number(value) 判断变量是否是数字
- string(value) 判断变量是否是字符串
- sequence(value) 判断变量是否是序列,比如字符串、列表、元组
- iterable(value) 判断变量是否可迭代
- mapping(value) 判断变量是否是匹配对象,比如字典
- sameas(value,other) 判断变量与other是否指向相同内存地址
使用方法
if左侧是测试器的第一个参数,其他参数可以写在括号内
{% if foo is sameas(bar) %}
也可以在右侧用空格链接
{% if foo is sameas bar %}
自定义测试器
和自定义过滤器类似,我们可以用Flask提供的app.template_test()装饰器来注册一个自定义测试器
例如
@app.template_test() def baz(n): if n == 'ok': return True else: return False
效果图
数字无效 之前的是以前写的,与这篇文章内容无关。
模板环境对象
Jinja2中,渲染行为由jinja2.Enviroment类控制,所有的配置选项、上下文变量、全局函数、过滤器和测试器都存储在Enviroment上。在与Flask结合后,我们不单独创建Enviroment对象,而是使用Flask创建的Enviroment对象,它存储在app.jinja_env上。
模板环境中的全局函数、过滤器和测试器分别存储在Enviroment对象的globals、filters和tests 属性中,这些都是字典对象。除了之前介绍的使用Flask装饰器和方法注册自定义函数,我们也可以直接操作这三个字典来添加相应的函数或变量。
例如
1.添加自定义全局对象
def bar(): return "I'm bar." foo = "I'm foo" app.jinja_env.globals['bar'] = bar app.jinja_env.globals['foo'] = foo
2.添加自定义过滤器
def smiling(s): return s + ':)' app.jinja_env.filters['smiling'] = smiling
3.添加自定义测试器
def baz(n): if n == 'ok': return True else: return False app.jinja_env.tests['baz'] = baz
模板结构组织
局部模板
在Web程序里,我们通常会为每一类页面写一个独立的模板。比如主页模板、用户登陆模板。这些模板可以直接在视图函数中渲染并作为HTML响应主体。除了这些模板以外,我们还会用到另外一些模板,他们就是局部模板或者叫次模板,因为他们仅包含部分代码,所以我们不会在视图函数中渲染它,而是插入到其他独立模板中。
当多个独立模板需要用到同一块HTML代码时,我们可以把这段代码抽离出来作为一个局部模板。这样可以避免重复,同时也更好地进行统一管理。
例如,多个页面中都要显示一个同样的提示条 ,我们把这个提示条单独写在一个HTML文件中,假设它就叫_banner.html。
我们使用include标签来插入局部模板,这会把局部模板的内容插入到使用这个include标签的位置。也就是说我们可以在任意模板中用以下代码插入_banner.html的内容:
{% include '_banner.html' %}