jinja2 自定义filter 模板语法

原创
2014/08/08 11:13
阅读数 2.5K

自定义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>

模板语法文档

概要:

 一个模板就是一个简单的文本文件它可以生成任何基于文本的格式(HTML, XML, CSV, LaTeX 等等), 没有明确的扩展名, .html, .xml 或者其他任何都可以.模板包含变量(或表达式), 当模板被评估(解析)的时候这些变量会被替换成值.

模板有一些标签用来控制模板解释时的逻辑.模板的语法受Djangopython影响严重.

{% %}用来执行语句,

{{ }}用来返回一个变量的值.

    一个最小的基本实现。

<!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>

变量:

可以使用.号来获取对象的属性或者[]访问,如果变量或属性不存在会返回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 对象


   

过滤器:

 变量的修改可以使用过滤器.过滤器的语法是使用管道操作符|, 过滤器可以多重嵌套使用前面的过滤器的返回值将会作为下一个过滤器的第一个输入参数.   这里的管道和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过滤器


展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部