QWeb是一个基于xml的模板引擎,用于生成HTML片断和页面,模板指令是写在xml标签中的以t-开头的属性,好比t-if
若是要让一个标签不被渲染,能够采用t来包裹,这样会执行它里面的命令可是不产生任何输出javascript
<t t-if="condition"> <p>Test</p> </t> #condtition为true时上述代码会输出:<p>Test</p> <div t-if="condition"> <p>Test</p> </div> #condtition为true时上述代码会输出: <div> <p>Test</p> </div>
Qweb有一个自动过滤xss和html的输出命令esc,它接受一个表达式,解析变输出结果:css
<p><t t-esc="value"/></p> #当value值为42时输出结果: <p>42</p>
还有一个raw参数与esc相似,但不过滤html,用于显示处理好的html内容
html
qweb有一个if条件判断指令,会自动解析其对应的属性值里的表达式:java
<div> <t t-if="condition"> <p>ok</p> </t> </div> #当condition是true的时候解析成: <div> <p>ok</p> </div> #condition为false的时候解析成 <div> </div> #也可用下面的方法实现同样的功能 <div> <p t-if="condition">ok</p> </div>
另外,t-elif
和t-else
可用于添加条件分支node
<div> <p t-if="user.birthday == today()">Happy bithday!</p> <p t-elif="user.login == 'root'">Welcome master!</p> <p t-else="">Welcome!</p> </div>
Qweb有一个指令用于循环处理,t-foreach用来指定须要循环处理的数据,t-as提供的是在后面用于表明当前项目的变量名:python
<t t-foreach="[1, 2, 3]" t-as="i"> <p><t t-esc="i"/></p> </t> #上述语句输出: <p>1</p> <p>2</p> <p>3</p> #也可用下面的方法实现同样的功能 <p t-foreach="[1, 2, 3]" t-as="i"> <t t-esc="i"/> </p>
foreach可用于数组(当前项目便是值)、映射表(当前项目是key)、整形数字(至关于0-X的数组)jquery
* $as_all - 被循环的对象 * `$as_value` - 当前循环的值,当处理列表和数字时与 `$as`是同样的,当处理映射表时它表明值,而`$as`表明的是键 * $as_index - 当前循环索引,第0开始计算 * $as_size - 被循环对象的大小 * $as_first - 当前项目是不是第一个,至关于$as_index == 0 * $as_last - 当前项目是不是最后一个,至关于$as_index + 1 == $as_size * $as_parity - 当前项目是奇数个仍是偶数 * $as_even - 当前项目索引是否为奇数 * $as_odd - 当前项目索引是否为偶数
上述参数只在foreach里面可用,但可在循环的最后复制到全局环境中web
<t t-set="existing_variable" t-value="False"/> <!-- existing_variable now False --> <p t-foreach="[1, 2, 3]" t-as="i"> <t t-set="existing_variable" t-value="True"/> <t t-set="new_variable" t-value="True"/> <!-- existing_variable and new_variable now True --> </p> <!-- existing_variable always True --> <!-- new_variable undefined -->
qweb能够对属性进行实时计算并在输出时设置,经过t-attr来实现,有三种形式:数据库
t-att-$name
能够建立一个名为$name
的属性,原属性的值会被解析为新生成的属性的值<div t-att-a="42"/> #输出 <div a="42"></div>
t-attf-$name
与第一个相似,但它的值是一个格式化字符串而不是表达式,通常用于字符+变量组合如:<t t-foreach="[1, 2, 3]" t-as="item"> <li t-attf-class="row {{ item_parity }}"><t t-esc="item"/></li> </t> #输出: <li class="row even">1</li> <li class="row odd">2</li> <li class="row even">3</li>
t-att=mapping
若是参数是映射表,每一个键值对会生成一个属性:<div t-att="{'a': 1, 'b': 2}"/> #输出 <div a="1" b="2"></div>
t-att=pair
若是参数是元组或2个元素的数组,那么第一个项就做为属性名,第二个做为属性值<div t-att="['a', 'b']"/> #输出 <div a="b"></div>
qweb容许在模板内设置变量(用于记住一个计算结果、或为数据定义一个更明确的名字)
使用t-set来实现,它的值就是设置的变量名json
<t t-set="foo" t-value="2 + 1"/> <t t-esc="foo"/> #输出3
<t t-set="foo"> <li>ok</li> </t> <t t-esc="foo"/> #输出结果 <li>ok</li> #内容被esc自动输义了
qweb能够用于最高级别的渲染,但也能够经过t-call
来包含其余模板<t t-call="other-template"/>
会调用指定名字的模板
若是other-template是<p><t t-value="var"/></p>
获得的结果会是<p/>
<t t-set="var" t-value="1"/> <t t-call="other-template"/> #会输出 <p>1</p>
这个有一个问题,在t-call外其余位置会可见。在t-call内设置的内容会在调用子模板时先执行并更新到当前环境
<t t-call="other-template"> <t t-set="var" t-value="1"/> </t>
t-call内包含的内容能够经过一个0的魔术变量来传递给被调用的模板:
#other-template <div> This template was called with content: <t t-raw="0"/> </div> #main <t t-call="other-template"> <em>content</em> </t> #output <div> This template was called with content: <em>content</em> </div>
t-field
只能用于格式化记录字段(从browe函数获取到的),能够根据字段类型自动匹配格式;t-options
只能用于自定义字段,最经常使用的是widget
,其余的选项都是field-xx
或widget-xx
经过PDB 的set_trace 来进行调试,接收的参数须要是模块名字,set_trace()会在该模块上调用<t t-debug="pdb"/>
至关于:importlib.import_module("pdb").set_trace()
odoo.http.HttpRequest.render()
来渲染保存在数据库中的模板response = http.request.render('my-template', { 'context_value': 42 }) #会直接从controller里返回一个响应对象
比上面的更深层次的helper是在ir.ui.view:
中的render方法
ir.ui.view
记录会自动加载,它会为渲染环境设置一系列默认值keep_query - 一个keep_query函数,参数1:values-传递给qweb的上下文环境,参数2:engine (str) 用于qweb渲染的odoo模型名
<templates> <t t-name="template-name"> <!-- template code --> </t> </templates>
它没有其余参数,但可使用一个t标签,当使用t标签时它须要有单个子元素,模板名能够随便取,通常会用.
分隔来表示继承关系
t-extend
来表示,它的值是被继承的模板名,经过t-jquery来进行修改<t t-extend="base.template"> <t t-jquery="ul" t-operation="append"> <li>new element</li> </t> </t>
t-jquery
给出的是一个css选择器,用于选择须要改变的节点,并经过t-operation
指定须要进行的操做
replace - 新节点内容直接替换原节点
若是没有指定operation,那么模板内容会被解析成javascript节点,并将context节点设置为this
<t t-set="foo" t-value="42"/> <t t-log="foo"/> #在控制台输出42
在渲染时触发一个调试断点
<t t-if="a_test"> <t t-debug=""> </t>
该节点内容里的javascript代码会在渲染时执行,接收一个context参数,将当前的环境传给js
<t t-set="foo" t-value="42"/> <t t-js="ctx"> console.log("Foo is", ctx.foo); </t>
core.qweb(core是web.core
模块):一个 QWeb2.Engine()实例,在这个实例中全部模块相关模板文件所有有加载,并且可以使用_
(underscore方法), _t
(翻译方法) 和 JSON
core.qweb.render 能够用于渲染基本模块的模板
QWeb渲染器,处理qweb的大部分逻辑如加载、解析、编译、渲染
odoo在core模块中将user实例化,并输出到core.qweb,同时将全部模板文件加载到qweb实例中
一个 QWeb2.Engine()同时也能够当成一个命名空间来看待
QWeb2.Engine.render(template[, context])
将一个模板渲染成字符串,使用context来查找渲染时所遇到的变量
参数:1.template (String) - 须要渲染的模板名
2.context (Object) - 渲染时须要用到的命名空间
这个方法在某些状况下比较有用,用于本身定义一个命名空间并得到单独的 QWeb2.Engine()实例,这样不要担忧与其余模块冲突。
该方法加载指定的模板,参数能够是如下几种:
1.XML字符串 -- Qweb会将它解析成xml文档并加载
2.URL -- Qweb会下载对应的url内容,并加载得到的xml字符串
3.Document 或 Node -- qweb会将全部第一级的子节点过滤一遍,并加载命名为template或从template继承的部分
布尔型标志表示引擎是否使用调试模式,默认状况下,qweb会把模板执行过程当中产生的错误拦截,在调试模式下,全部异常都会被保留
在模板继承处理时所使用的jQuery实例,默认是window.jQuery
一个方法,当它出现时会在编译dom节点和template节点前调用,通常用于自动模板中的翻译文本内容或属性,默认是null