Odoo前端页面模版渲染引擎——Jinja2用法教程
转载请注明原文地址:https://www.cnblogs.com/cnodoo/p/9307200.html
一:渲染模版
要渲染一个qweb模板文件,通过render_template
方法即可。
@app.route('/about/') def about(): # return render_template('about.html',user='username') return render_template('about.html',**{'user':'username'})
渲染模版时有两种传递参数的方式:用 var='value' 传递一个参数;使用字典组织多个参数,并且加两个*
号转换成关键字参数传入。
二:模板概要
Jinja
模板是简单的一个纯文本文件,一般用html页面来书写。
1. <html lang="en"> 2. <head> 3. <title>My Webpage</title> 4. </head> 5. <body> 6. <ul id="navigation"> 7. {% for item in navigation %} 8. <li><a href="{{ item.href }}">{{ item.caption }}</a></li> 9. {% endfor %} 10. </ul> 11. 12. {{ a_variable }} 13. {{ user.name }} 14. {{ user['name'] }} 15. 16. {# a comment #} 17. </body> 18.</html> 转自作者:IT蔷薇 链接:http://www.jianshu.com/p/31a75d3d9270
模版讲解:
{{ ... }}
:装载一个变量,模板渲染的时候,会使用传进来的同名参数这个变量代表的值替换掉。{% ... %}
:装载一个控制语句。{# ... #}
:装载一个注释,模板渲染的时候会忽视这中间的值。
三:变量
1)在模板中添加变量,可以使用(set)语句。
{% set name='xx' %}
之后就可以在页面文件中使用name这个变量了。在解释性语言中,变量的类型时运行时确定的,因此,这里的变量可以赋任何类型的值。
上面的语句创建的是全局变量,从定义之后的文件部分中都可以访问 。
2)局部变量
可以使用with
语句来创建一个内部的作用域,将set
语句放在其中,这样创建的变量只在with
代码块中才有效。
{% with foo = 42 %} {{ foo }} {% endwith %}
这样,foo变量就只能在with标签间可以使用。
四:控制语句
控制语句都是放在{% ... %}
中,并且有一个语句{% endxxx %}
来进行结束。
1:if语句
{% if kenny.sick %} Kenny is sick. {% elif kenny.dead %} You killed Kenny! You bastard!!! {% else %} Kenny looks okay --- so far {% endif %} 转自:IT蔷薇 链接:http://www.jianshu.com/p/31a75d3d9270
2:for循环
1)普通用法
<ul> {% for user in users %} <li>{{ user.username|e }}</li> {% endfor %} </ul>
2)遍历字典
{% for key, value in my_dict.iteritems() %} <dt>{{ key|e }}</dt> <dd>{{ value|e }}</dd> {% endfor %}
3)在循环中加入else
<ul> {% for user in users %} <li>{{ user.username|e }}</li> {% else %} <li><em>no users found</em></li> {% endfor %} </ul>
4)Jinja2中for循环内置常量
loop.index | 当前迭代的索引(从1开始) |
loop.index0 | 当前迭代的索引(从0开始) |
loop.first | 是否是第一次迭代,返回True\/False |
loop.last | 是否是最后一次迭代,返回True\/False |
loop.length | 序列的长度 |
注意:不可以使用continue
和break
表达式来控制循环的执行。
五:运算符
+
号运算符:可以完成数字相加,字符串相加,列表相加。但是并不推荐使用+
运算符来操作字符串,字符串相加应该使用~
运算符。-
号运算符:只能针对两个数字相减。/
号运算符:对两个数进行相除。%
号运算符:取余运算。*
号运算符:乘号运算符,并且可以对字符进行相乘。**
号运算符:次幂运算符,比如2**3=8。in
操作符:跟python中的in
一样使用,比如{{1 in [1,2,3]}}
返回true
。~
号运算符:拼接多个字符串,比如{{"Hello" ~ "World"}}
将返回HelloWorld
。
六:Jiaja2模版最重要的部分——宏(碎片)
{% macro input(name, value='', type='text') %} <input type="{{ type }}" name="{{ name }}" value="{{ value|e }}"> {% endmacro %}
在其它地方使用这个宏快速创建出符合要求的input标签:
<p>{{ input('username') }}</p> <p>{{ input('password', type='password') }}</p>
1)页面文件中导入宏——import
在开发中,会将一些常用的宏单独放在一个文件中,在需要使用的时候,再从这个文件中进行导入。
import
语句的用法跟python
中的import
类似,可以直接import...as...
,也可以from...import...
或者from...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>
导入模板并不会把当前上下文中的变量添加到被导入的模板中,我们可以在导入的时候使用with context 把上下文传进去:
{% from '_helpers.html' import my_macro with context %}
2)宏文件中引用其它宏——include
include
语句可以把一个模板引入到另外一个模板中,类似于把一个模板的代码copy到另外一个模板的指定位置。
{% include 'header.html' %} Body {% include 'footer.html' %}
七:模版文件的继承
模板可以继承,通过继承可以把模板中许多重复出现的元素抽取出来,放在父模板中,并且父模板通过定义block
给子模板开一个口,子模板根据需要,再实现这个block进行具体内容定义。
比如:父模版base.html如下:
<!DOCTYPE html> <html lang="en"> <head> {% block head %} //开放一个地方,以待具体赋值 <link rel="stylesheet" href="style.css" /> <title>{% block title %}{% endblock %} - My Webpage</title> {% endblock %} </head> <body> <div id="content">{% block content %}{% endblock %}</div> <div id="footer"> {% block footer %} © Copyright 2008 by <a href="http://domain.invalid/">you</a>. {% endblock %} </div> </body> </html> 转自:IT蔷薇 链接:http://www.jianshu.com/p/31a75d3d9270
然后定义子模版,对父模板中的block部分进行覆盖书写:
{% extends "base.html" %}//1:继承父模板 {% block title %}Index{% endblock %}//2:书写title block {% block head %}//3:书写head block {{ super() }}//调用父模板中的内容,如果不调用,则此处会被子模板中书写的内容覆盖掉 <style type="text/css"> .important { color: #336699; } </style> {% endblock %} {% block content %}//4:书写content block <h1>Index</h1> <p class="important"> Welcome to my awesome homepage. </p> {% endblock %} 转自:IT蔷薇 链接:http://www.jianshu.com/p/31a75d3d9270
另外:模板文件中对block内容的调用,可以使用 self.blockName 的方式。
<title>{% block title %}{% endblock %}</title> <h1>{{ self.title() }}</h1>//调用title block的内容
注意:在子模板中,所有的标签和代码都要添加到从父模板中继承的block
中。否则,这些文本和标签将不会被渲染。(因为子模板相当于把内容嵌入到父模板到block中,而没有写到block中的内容当然不会被嵌入,也就不会被渲染。)
八:过滤器
过滤器是通过(|
)符号进行使用的,例如:{{ name|length }}:
将返回name的长度。
过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。
Jinja2拥有许多过滤器:(转自:http://www.jianshu.com/p/31a75d3d9270)
abs(value)
:返回一个数值的绝对值。示例:-1|abs
default(value,default_value,boolean=false)
:如果当前变量没有值,则会使用参数中的值来代替。示例:name|default('xiaotuo')
——如果name不存在,则会使用xiaotuo
来替代。boolean=False
默认是在只有这个变量为undefined
的时候才会使用default
中的值,如果想使用python
的形式判断是否为false
,则可以传递boolean=true
。也可以使用or
来替换。escape(value)或e
:转义字符,会将<
、>
等符号转义成HTML中的符号。示例:content|escape
或content|e
。first(value)
:返回一个序列的第一个元素。示例:names|first
format(value,*arags,**kwargs)
:格式化字符串。比如:{{ "%s" - "%s"|format('Hello?',"Foo!") }} 将输出:Helloo? - Foo!
last(value)
:返回一个序列的最后一个元素。示例:names|last
。length(value)
:返回一个序列或者字典的长度。示例:names|length
。join(value,d=u'')
:将一个序列用d
这个参数的值拼接成字符串。safe(value)
:如果开启了全局转义,那么safe
过滤器会将变量关掉转义。示例:content_html|safe
。int(value)
:将值转换为int
类型。float(value)
:将值转换为float
类型。lower(value)
:将字符串转换为小写。upper(value)
:将字符串转换为小写。replace(value,old,new)
: 替换将old
替换为new
的字符串。truncate(value,length=255,killwords=False)
:截取length
长度的字符串。striptags(value)
:删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。trim
:截取字符串前面和后面的空白字符。string(value)
:将变量转换成字符串。wordcount(s)
:计算一个长字符串中单词的个数。
九:测试器
测试器主要用来判断一个值是否满足某种类型,语法是:if...is...:
{% if variable is escaped%} value of variable: {{ escaped }} {% else %} variable is not escaped {% endif %}
Jinja2中测试器有
:
callable(object)
:是否可调用。defined(object)
:是否已经被定义了。escaped(object)
:是否已经被转义了。upper(object)
:是否全是大写。lower(object)
:是否全是小写。string(object)
:是否是一个字符串。sequence(object)
:是否是一个序列。number(object)
:是否是一个数字。odd(object)
:是否是奇数。even(object)
:是否是偶数。
十:转义
在模板渲染字符串的时候,字符串有可能包括一些非常危险的字符比如<
、>
等,这些字符会破坏掉原来HTML
标签的结构,更严重的可能会发生XSS
跨域脚本攻击,因此如果碰到<
、>
这些字符的时候,应该转义成HTML
能正确表示这些字符的写法。
对于一些不信任的字符串,可以通过{{ content_html|e }}
或者是{{ content_html|escape }}
的方式进行转义。
如果想关闭自动转义,可以通过{{ content_html|safe }}
的方式关闭自动转义。
{%autoescape true/false%}...{%endautoescape%}
可以将一段代码块放在中间,来关闭或开启自动转义:
{% autoescape false %} <p>autoescaping is disabled here <p>{{ will_not_be_escaped }} {% endautoescape %}
十一:模版页面中引入静态文件
静态文件主要包括有CSS
样式文件、JavaScript
脚本文件、图片文件、字体文件等静态资源。
在Jinja
中加载静态文件只需要通过url_for
全局函数就可以实现:
<link href="{{ url_for('static',filename='about.css') }}">
引入static目录下的about.css文件。
Odoo前端页面模版渲染引擎——Jinja2用法教程的更多相关文章
- odoo 前端页面渲染--数据库管理页面
例子 - 去除登陆页面的Powered by Odoo链接从上面的第3步,我们可以看到,最后登录界面是由'web.login' 模板来显示的,通过odoo的继承方式,我们很容易的就可以去除这个链接,通 ...
- JavaScript 如何工作:渲染引擎和性能优化技巧
翻译自:How JavaScript works: the rendering engine and tips to optimize its performance 这是探索 JavaScript ...
- How Javascript works (Javascript工作原理) (十一) 渲染引擎及性能优化小技巧
个人总结:读完这篇文章需要20分钟,这篇文章主要讲解了浏览器中引擎的渲染机制. DOMtree ----| |----> RenderTree CSSOMtree ----| ...
- JavaScript 工作原理之十一-渲染引擎及性能优化小技巧
原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第十一章. 迄 ...
- SpringBoot入门篇--使用Thymeleaf模板引擎进行页面的渲染
在做WEB开发的时候,我们不可避免的就是在前端页面之间进行跳转,中间进行数据的查询等等操作.我们在使用SpringBoot之前包括我在内其实大部分都是用的是JSP页面,可以说使用的已经很熟悉.但是我们 ...
- jquery jtemplates.js模板渲染引擎的详细用法第二篇
jquery jtemplates.js模板渲染引擎的详细用法第二篇 关于jtemplates.js的用法在第一篇中已经讲过了,这里就直接上代码,不同之处是绑定模板的方式,这里讲模板的数据专门写一个t ...
- jquery jtemplates.js模板渲染引擎的详细用法第一篇
jquery jtemplates.js模板渲染引擎的详细用法第一篇 Author:ching Date:2016-06-29 jTemplates是一个基于JQuery的模板引擎插件,功能强大,有了 ...
- 渲染引擎 & 页面渲染流程 & 阻塞
文档对象模型(Document Object Model,简称DOM) 浏览器渲染引擎 一个渲染引擎 主要模块: HTML 解析器 解释 HTML 文档的解析器,将 HTML 文本 解析成 DOM 树 ...
- jquery jtemplates.js模板渲染引擎的详细用法第三篇
jquery jtemplates.js模板渲染引擎的详细用法第三篇 <span style="font-family:Microsoft YaHei;font-size:14px;& ...
随机推荐
- 手动实现一个简单的ArrayList
import org.omg.CORBA.PUBLIC_MEMBER; import java.io.Serializable; import java.util.*; import java.uti ...
- ZAB 算法
ZAB (Zookeeper Atomic Broadcast ) zookeeper原子消息广播协议 保证:分布式数据一致性 所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为 ...
- Extjs checkbox数值回显
昨天上午花了半天时间都在调 extjs的编辑页面里的CheckBox的回显问题,一直没搞定,毕竟我接触extjs才一个月不到,属于小白.先上个图: 这就是编辑页面的时候,需要的效果.然后我代码里是用了 ...
- 关于android R.layout 中找不到已存在的布局文件问题的解决
今天遇到一个很奇怪的问题,打R.layout.,居然不会提示已经写好的布局文件,自己把xml文件名打下去后,居然提示错误. 开始以为是R文件中没有自动生成关于布局文件对应的整型,看了R文件,其实是有生 ...
- js/jq动态创建表格的行与列
之前做了一个项目,需求是能动态创建表格行,动态创建表格的列,度了很多资料,都没有动态创建列的插件,所以自己动手写了一个 需求大概是(下图) 1.动态添加一行.2.动态添加一列,3.删除行.4.删除列, ...
- mysqli 查询
$mysqli = new mysqli('localhost', 'user', 'pwd', 'dbname'); $query = "select goods_id,goods_nam ...
- Laravel 支付宝支付异步通知
支付宝支付通知有前端通知(GET)和服务器异步通知(POST) 在配置支付宝支付时,需要注意的问题就是支付宝的回调操作: 1.在laravel中应该将支付宝通知路径组织csrf验证,否则会导致419错 ...
- XSS 相关 payload 集合
Ajax 获取数据 GET function loadXMLDoc() { var xmlhttp; if (window.XMLHttpRequest){// code for IE7+, Fire ...
- webpack必知必会
细节 url-loader和file-loader是什么关系? file-loader用于将文件路径打包为另一个url,url-loader封装了file-loader.使用url-loader时,只 ...
- zTree设置异步加载后展开
//不能直接配置展开属性 因为没有数据,需要添加回调函数,异步加载成功展开 callback: { onAsyncSuccess: zTreeOnAsyncSuccess } //异步加载成功回调函数 ...