Odoo12开发文档之QWbe

前言

下篇文章将用一个案例来演示


简介

QWeb是Odoo使用的主要模板引擎。它是一个XML模板引擎,主要用于生成HTML片段和页面。


QWeb标签

数据输出

QWeb有一个主输出指令,当显示用户提供的内容时,它会自动HTML转义其限制XSS风险的内容:esc

esc 获取表达式,对其进行评估并打印内容:

<p> <t t-esc="value" /> </p>

value的值设置为42进行渲染:

<p>42</p>

还有另一个其他输出指令raw,其行为与esc相同,但不对其输出进行HTML转义。

条件语句

QWeb有一个条件指令if,用于计算作为属性值给出的表达式:

<div> 
    <t t-if="condition"> 
        <p>ok</p> 
    </t> 
</div>

如果条件为真,则呈现元素:

<div> 
    <p>ok</p> 
</div>

但如果条件为假,则从结果中删除:

<div> 

</div>

条件呈现适用于指令的承载,不一定要套在 < t > 标签:

<div> 
	<p  t-if="condition"> ok </p>
</div>

同样的额外的条件分支指令t-elift-else也可用:

<div> 
    <p  t-if="user.birthday==today()">祝你生日愉快</p> 
    <p  t-elif="user.login=='root'" >欢迎管理员</p> 
    <p  t-else="" >欢迎</p> 
</div>

循环输出

QWeb有一个迭代指令foreach,它使表达式返回集合以进行迭代,第二个参数t-as提供用于迭代“当前项”的名称:
(类似Vue里面的v-for)

<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可以迭代一个数组(当前项将是当前值),一个映射(当前项将是当前键)或一个整数(相当于在0和0之间的数组上迭代和提供的整数不包括)。
除了通过t-as传递的名称之外,foreach还为各种数据点提供了一些其他变量:

提示
$as将被传递给t-as的名称替换

$as_all
迭代的对象
(此变量仅适用于JavaScript QWeb,而不适用于Python)

$as_value
当前迭代值,与 $as和列表和整数相同,但对于映射,它提供值(其中 $as提供键)

$as_index
当前迭代索引(迭代的第一项索引为0)

$as_size
集合的大小(如果可用)

$as_first
当前项是否是迭代的第一个(相当于 $as_index == 0)

$as_last
当前项是否是迭代的最后一项(相当于 $ as_index + 1 == $ as_size),要求iteratee的大小可用

$as_parity
“偶数”或“奇数”,当前迭代轮次的奇偶校验

$as_odd
一个布尔标志,指示当前迭代轮次在奇数索引上

这些额外变量和创建的所有新变量仅在foreach的范围内可用。如果变量存在于foreach上下文之外,则该值将在foreach的末尾复制到全局上下文中。

<t t-set="existing_variable" t-value="False"/>
<!-- existing_variable现在为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和new_variable现在为True -->
</p>

<!-- existing_variable始终为True -->
<!-- new_variable undefined -->

属性

QWeb可以即时计算属性并在输出节点上设置计算结果。这是通过t-att(属性)指令完成的,该指令以3种不同的形式存在:

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允许从模板中创建变量,记忆计算(多次使用),给数据赋予更清晰的名称,…

这是通过set指令完成的,该指令使用要创建的变量的名称。要设置的值可以通过两种方式提供:

  • 包含表达式的t-value属性及其计算结果将被设置:
<t t-set="foo" t-value="2 + 1"/>
<t t-esc="foo"/>

结果输出3

  • 如果没有t-value属性,则渲染节点的主体并将其设置为变量的值:
<t t-set="foo">
    <li>ok</li>
</t>
<t t-esc="foo"/>

将生成 &lt; li&gt; ok&lt; / li&gt;(内容在我们使用esc指令时被转义)

使用此操作的结果是raw指令的重要用例

调用子模板

QWeb模板可以用于顶级渲染,但也可以使用t-call指令从另一个模板中使用(以避免重复或为部分模板命名):

<t t-call="other-template"/>

如果other_template定义为:

<p><t t-value="var"/></p>

上述调用将呈现为(无内容),但是:

<t t-set="var" t-value="1"/>
<t t-call="other-template"/>

将输出为 <p> 1 </p>

但是,这有一个问题,即从T-Call外部可见。或者,在调用子模板之前,将对call指令体中设置的内容进行评估,并且可以更改本地上下文:

<t t-call="other-template">
    <t t-set="var" t-value="1"/>
</t>
<!-- 这里不存在“var” -->

call指令的主体可以是任意复杂的(不仅仅是set指令),它的呈现形式可以在被调用的模板中作为一个神奇的0变量:

<div>
    此模板是用内容调用的:
    <t t-raw="0"/>
</div>

因此被称为:

<t t-call="other-template">
    <em>内容</em>
</t>

会导致:

<div>
    此模板是用内容调用的:
    <em>内容</em>
</div>

Python专用指令

“智能记录”字段格式化

t-field指令只能在对“智能”记录(browse方法的结果)执行字段访问(a.b)时使用。它能够根据字段类型自动格式化,并集成在网站的富文本版本中。
t-options可用于自定义字段,最常见的选项是小部件widget,其他选项依赖于字段field或widget-dependent。

debug

使用PDB的set_trace API调用调试器。参数应该是模块的名称,在该模块上调用set_trace方法:

<t t-debug="pdb"/>

相当于importlib.import_module("pdb").set_trace()

请求

QWeb的大多数Python端用途都在控制器中(以及在HTTP请求期间),在这种情况下,通过调用odoo.http.HttpRequest.render()可以轻松地呈现存储在数据库中的模板(作为视图):

response = http.request.render('my-template', {
    'context_value': 42
})

这会自动创建一个Response对象,该对象可以从控制器返回(或进一步自定义)。

视图

比上一个更深层次的是ir.ui.view上的render方法:

render(cr, uid, id[, values][, engine='ir.qweb][, context])
根据数据库id或外部id呈现QWeb视图/模板。模板自动从ir.ui.view加载。

在渲染上下文中设置一些默认值:

request
当前的WebRequest对象,如果有的话

debug
当前请求(如果有)是否处于调试模式

quote_plus
URL编码实用程序函数

json
相应的标准库模块

time
相应的标准库模块

datetime
相应的标准库模块

keep_query
keep_query帮助函数


Javascript专用指令

定义模版

t-name指令只能放在模板文件的顶层(将子级指向文档根目录):

<templates>
    <t t-name="template-name">
        <!-- 模板代码 -->
    </t>
</templates>

它不需要其他参数,但可以与 <t>元素或任何其他元素一起使用。使用元素时,<t>应只有一个子元素。

模板名称是一个任意字符串,尽管当多个模板相关时(例如,称为子模板),通常使用点分隔名称来表示层次关系。

模版继承

模板继承用于就地更改现有模板,例如向其他模块创建的模板添加信息。

模板继承是通过t-extend指令执行的,该指令将要更改的模板的名称作为参数。

然后使用任意数量的t-jquery子指令执行更改:

<t t-extend="base.template">
    <t t-jquery="ul" t-operation="append">
        <li>新元素</li>
    </t>
</t>

t-jquery指令采用CSS选择器。此选择器用于扩展模板,以选择应用指定t-operation的上下文节点:

append
节点的主体附加在上下文节点的末尾(在上下文节点的最后一个子节点之后)

prepend
节点的主体附加在上下文节点开头(插入到上下文节点的第一个子节点之前)

before
节点的主体插入在上下文某节点之前

after
节点的主体插入在上下文某节点之后

inner
节点的主体替换上下文节点的子节点

replace
节点的主体用于替换上下文节点本身

未指定 operation
如果没有指定t-operation,模板主体将被解释为javascript代码,并以此方式与上下文节点一起执行。

警告
虽然比其他操作更强大,但这种模式也很难调试和维护,建议避免使用它

debug

javascript QWeb实现提供了一些调试钩子

t-log
获取表达式参数,在呈现过程中对表达式求值,并使用console.log记录其结果:

<t t-set="foo" t-value="42"/>
<t t-log="foo"/>

将打印42到控制台

t-debug
在模板渲染期间触发调试器断点:

<t t-if="a_test">
    <t t-debug="">
</t>

如果调试处于活动状态,将停止执行(具体情况取决于浏览器及其开发工具)

t-js
节点的主体是在模板渲染期间执行的javascript代码。获取一个上下文参数,该参数是t-js主体中呈现上下文可用的名称:

<t t-set="foo" t-value="42"/>
<t t-js="ctx">
    console.log("Foo is", ctx.foo);
</t>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值