【Flask】扩展:Jinja2 模板(二)

Jinja2 测试器

Jinja2中的测试器和过滤器非常相似,区别是测试器总是返回一个布尔值,它可以用来测试一个变量或者表达式,需要用is关键字来进行测试。测试器一般都会跟着if控制语句一起使用。

  • • 内置测试器

  {% if variable is escaped%}
      value of variable: {{ escaped }}
  {% else %}
      variable is not escaped
  {% endif %}

以上判断variable这个变量是否已经被转义了,Jinja中内置了许多的测试器,看以下列表:

测试器 说明
callable(object) 检查是否可调用。
defined(value) 检查是否已经被定义了。
divisibleby(value, num) 检查是否可以被数字整除。
equalto(value, other) 检查一个对象是否与另一个对象具有相同的值。
escaped(value) 检查是否已经被转义了。
even(value) 检查是否是偶数。
iterable(value) 检查是否可以迭代对象。
lower(value) 检查是否全是小写。
mapping(value) 如果对象是映射(dict 等),则返回 true。
none(value) 如果变量为无,则返回真。
number(object) 检查是否是一个数字。
odd(object) 检查是否是奇数。
sameas(value, other) 检查一个对象是否与另一个对象指向相同的内存地址。
sequence(value) 检查是否是一个序列。
string(value) 检查是否是一个字符串。
undefined(value) 类似于defined()。
upper(value) 检查是否全是大写。

参考示例:

{# 检查变量是否被定义,也可以用undefined检查是否未被定义 #}
{% if name is defined %}
    <p>Name is: {{ name }}</p>
{% endif %}

{# 检查是否所有字符都是大写 #}
{% if name is upper %}
  <h2>"{{ name }}" are all upper case.</h2>
{% endif %}

{# 检查变量是否为空 #}
{% if name is none %}
  <h2>Variable is none.</h2>
{% endif %}

{# 检查变量是否为字符串,也可以用number检查是否为数值 #}
{% if name is string %}
  <h2>{{ name }} is a string.</h2>
{% endif %}

{# 检查数值是否是偶数,也可以用odd检查是否为奇数 #}
{% if 2 is even %}
  <h2>Variable is an even number.</h2>
{% endif %}

{# 检查变量是否可被迭代循环,也可以用sequence检查是否是序列 #}
{% if [1,2,3] is iterable %}
  <h2>Variable is iterable.</h2>
{% endif %}

{# 检查变量是否是字典 #}
{% if {'name':'test'} is mapping %}
  <h2>Variable is dict.</h2>
{% endif %}
  • • 自定义测试器如果内置测试器不满足需求,需要自定义,写法类似于过滤器,现在Flask应用代码中定义测试器函数,然后通过add_template_test将其添加为模版测试器:

  import re
  from flask import FLask
  
  app = Flask(__name__)
  
  def has_number(str):
      return re.match(r'.*d+'str)
  
  app.add_template_test(has_number, 'contain_number')
  
  if __name__ == '__main__':
      app.run(debug=True)

定义了一个has_number函数,用正则来判断输入参数是否包含数字。然后调用app.add_template_test方法,第一个参数是测试器函数,第二个是测试器名称,可以在模版中contain_number测试器。

{% if name is contain_number %}
    <h2>"{{name}}" contain_number</h2>
{% endif %}

同过滤器一样,Flask提供了添加测试器的装饰器template_test。下面的代码就添加了一个判断字符串是否已某一个串结尾的测试器。装饰器的参数定义了该测试器的名称end_with

@app.template_test('end_with')
def end_with(str, suffix):
    return str.lower().endswith(suffix.lower())

在模版中可以这样使用:

{% if name is end_with "me" %}
    <h2>"{{ name }}" ends with "me".</h2>
{% endif %}

Flask添加测试器的方法是封装了对Jinji2环境变量的操作,上述添加end_with测试的方法,等同于下面方式。

app.jinja_env.tests['end_with'] = end_with

Flask应用中,不建议直接访问Jinja2的环境变量。如果离开Flask环境直接使用Jinja2的话,就可以通过Jinja2.Environment来获取环境变量,并添加测试器。

Jinja2 宏和import

  • • 宏Jinja2模版中的宏跟python中的函数类似,可以传递参数,但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量。

  {% macro input(name, value='', type='text') %}
      <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}">
  {% endmacro %}

上述的代码定义了一个宏,宏的定义要加macro,宏定义结束要加endmacro标志,抽取出了一个inpurt标签,指定了一些默认参数,那么以后创建inpurt标签的时候,可以通过它快速的创建。

<p>{{ input('username') }}</p>
<p>{{ input('password', type='password') }}</p>
  • • import在真实的开发过程中,会将一些常用的宏单独放在一个文件中,在需要使用的时候,再从这个文件中进行导入。import语句的用法跟python中的import类似,可以直接import...as...,也可以form...import...或者from...import...as...

    • • 参考示例froms.html

 {% macro input(name, value='', type='text') %}
       <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
 {% endmacro %}
   
 {% macro textarea(name, value='', rows=10, cols=40) %}
     <textarea name="{{ name }}" rows="{{ rows }}" cols="{{ cols
       }}">{{ value|e }}</textarea>
 {% endmacro %}
  1. 1. import...as...形式

{% import 'forms.html' as forms %}
<dl>
<dt>Username</dt>
<dd>{{ forms.input('username') }}</dd>
<dt>Password</dt>
<dd>{{ forms.input('password', type='password') }}</dd>
</dl>
<p>{{ forms.textarea('comment') }}</p>
  1. 1. from...import...as.../from...import...形式

{% from 'forms.html' import input as input_field, textarea %}
<dl>
<dt>Username</dt>
<dd>{{ input_field('username') }}</dd>
<dt>Password</dt>
<dd>{{ input_field('password', type='password') }}</dd>
</dl>
<p>{{ textarea('comment') }}</p>

另外需要注意的是,导入模板并不会把当前上下文中的变量添加到被导入的模板中,如果你想要导入一个需要访问当前上下文变量的宏,有两种可能的方法:

  • • 显式地传入请求或请求对象的属性作为宏的参数。

  • • 与上下文一起(with context)导入宏。与上下文中一起(with context)导入的方式如下:

  {% from '_helpers.html' import my_macro with context %}

Jinja2 include和set语句

  • • include语句include语句可以把一个模版引入到另一个模版中,类似于把一个模版的代码copy到另外一个模版的指定位置。

  {% include 'header.html' %}
      主体内容
  {% include 'footer.html' %}
  • • 赋值(set)语句在模版中添加变量

  {% set name="Jinja2" %}   
  {% set navigation = [('index.html', 'Index'), ('about.html', 'About')] %}  <!-- 赋值为列表和元组 -->

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

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

也可以在with的后面直接添加变量,比如以上的写法可以修改成这样:

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

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


来源:网络

欢迎关注我的公众号“壹葉筆記”,技术文章第一时间推送。


原文始发于微信公众号(壹葉筆記):【Flask】扩展:Jinja2 模板(二)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/36106.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!