自定义Filter
和写一个函数没有区别,最主要的是把写好的过滤器注册到模板环境里,然后就是函数的第一个参数代表谁要知道
from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('/home/xyl/work/kpad2/templates'))
def filter1(value):
"""
dosomething
"""
return 123456
def filter2(value):
"""
dosomething
"""
value +=1000
return value
def filter3(value,arg):
"""
dosomething
"""
value +=arg
return value
env.filters['filter1'] = filter1
env.filters['filter2'] = filter2
env.filters['filter3'] = filter3
页面
<body>
{{ 1|filter1 }}<br>
{{ 2|filter2 }}<br>
{{ 2|filter3(10) }}<br>
</body>
模板语法文档
1 概要:
一个模板就是一个简单的文本文件, 它可以生成任何基于文本的格式(HTML, XML, CSV, LaTeX 等等), 没有明确的扩展名, .html, .xml 或者其他任何都可以.模板包含变量(或表达式), 当模板被评估(解析)的时候这些变量会被替换成值.
模板有一些标签, 用来控制模板解释时的逻辑.模板的语法受Django和python影响严重.
{% %}用来执行语句,
{{ }}用来返回一个变量的值.
一个最小的基本实现。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="en"> <head> <title>My Webpage</title> </head> <body> <ul id="navigation"> {% for item in navigation %} <li> <a href="{{ item.href }}">{{ item.caption }}</a> </li> {% endfor %} </ul> <h1>My Webpage</h1> {{ a_variable }} </body> </html>
2 变量:
可以使用.号来获取对象的属性或者[]访问,如果变量或属性不存在会返回undefined,
{{ foo.bar }} {{ foo['bar'] }}
查找实现方式:
foo.bar
1,foo.bar属性存在返回bar
2.bar in foo,迭代foo,bar在里面,返回bar
3 如果都不存在返回undefined 对象
foo['bar'] 正好和上面反者,所以要想快就得有针对性的使用,传可迭代的对象,用[] 比较好
1,bar in foo,迭代foo,bar在里面,返回bar
2,foo.bar属性存在返回bar
3 如果都不存在返回undefined 对象
3 过滤器:
变量的修改可以使用过滤器.过滤器的语法是使用管道操作符|, 过滤器可以多重嵌套使用, 前面的过滤器的返回值将会作为下一个过滤器的第一个输入参数. 这里的管道和linux的管道概念上是类似的, 将前面的表达式的返回值交给后面的表达式(或函数)处
{{ name|striptags|title }}
{{ list|join(', ') }}可以接受别的参数(第一个参数是|前面的值),像正常函数一样
4测试:
和filter类似, is前面的值将会被作为test的第一个参数传入, 如果还有其他的参数, test名称后面加空格跟随其他参数, 或者使用方法调用符”()”进行参数的传入.
5注释: {# #}中间包含注释语句.
6空白控制:
页面是什么样子的空白,就是什么杨空白,不会做任何改变。你也可以通过手工配置改变。
总觉得是为了美观,不影响任何实际使用
7转义:
这个和转义还有区别,应该是原样输出,原样的意思是不解析里面的任何表达式,看例子能明白
模板中:
<div>
{% raw %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endraw %}
实际产生页面:
{% for item in seq %}
{{ item }}
{% endfor %}
8:行语句
如果启用了行语句,是启用,不然没作用。下面两个相同
<ul> # for item in seq : <li>{{ item }}</li> # endfor </ul> <ul> {% for item in seq %} <li>{{ item }}</li> {% endfor %} </ul> 最好在后面加个:
要是没启用的话,
第一个在页面会输出下面的样子
# for item in (1,2,3) # endfor
9:模板继承
{% extends "base.html" %} 基本用法和django一样,一个base页面,写有很多block,子页面去填充block里的东西
在子页面也可以访问父页面里的内容
{% block sidebar %} <h3>Table Of Contents</h3> ... {{ super() }} 这里的super是指访问父页面{% block sidebar %}里的内容 {% endblock %}
定义结尾block名字,更方便阅读。开始和结束必须一致(这个是选的操作,不过看着确实有利于阅读)
{% block sidebar %} {% block inner_sidebar %} ... {% endblock inner_sidebar %} {% endblock sidebar %}
10:嵌套 和 范围
{% for item in seq %} <li>{% block loop_item %}{{ item }}{% endblock %}</li> {% endfor %} 上面的会报错,下面的是正确写法 {% for item in seq %} <li>{% block loop_item scoped %}{{ item }}{% endblock %}</li> {% endfor %}
在同一个模板中, 不允许有重名的block
在模板中, 可以通过self获取自身的引用来调用指定名字的block内容, 例如{{self.block_name }}
HTML Escaping
当从模板生成一个HTML的时候, 会由于变量包含一些HTML标签带来危险. 对于这个问题有两种解决方法: 手动转码每个变量或者通过默认指定自动转码所有的变量
Jinja2对两种解决方法都支持, 具体使用哪个根据应用程序的配置, 默认的配置是非自动转码.
默认使用手动转码的原因:
自动转码会对所有的变量都进行转码, 对于很多的变量实际上是不包含HTML元素的, 也就不会产生安全影响, 这样转码就会对性能带来影响.
变量的安全信息是非常脆弱的, 可能会因为转码和解码导致数据丢失.
手动转义
使用手动转码的工作方式:
对于可能包含>, <, &, “等字符的不可靠变量进行转码
转码使用管道调用filter: {{user.username | e}}
自动转义:
自动转义,对所有模板变量进行转义,如果不想转义一些变量 使用 |safe过滤器