odoo官方文档第十章 QWEB

QWEB

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

模板指令被指定为前缀为t-的XML属性,例如t-if for conditionals,其中元素和其他属性直接呈现。

为了避免元素呈现,占位符元素<t>也可用,它执行其指令但不会生成任何输出:

<t t-if="condition">
    <p>Test</p>
</t>

将导致:

<p>Test</p>

如果condition为真,但是:

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

将导致:

<div>
    <p>Test</p>
</div>

data output

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

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

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

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

<p>42</p>

还有另一个输出指令raw,其行为与esc相同,但不对其输出进行HTML转义。 显示单独构造的标记(例如,来自功能)或已经消毒的用户提供的标记可能是有用的。

conditionals

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

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

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

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

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

<div>
</div>

条件呈现适用于指令的承载,不必是<t>

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

将给出与前一个示例相同的结果。

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

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

loops

QWeb有一个迭代指令foreach,它接受一个返回集合的表达式迭代,第二个参数t-提供用于迭代“当前项”的名称:

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

与条件类似,foreach适用于带有指令属性的元素,和

<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

迭代的对象

$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_even

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

$as_odd

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

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

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

attributes

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>

setting variables

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指令的重要用例。

calling sub-templates

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-call外部可见的问题。 或者,将在调用子模板之前评估在call指令体中设置的内容,并且可以更改本地上下文:

<t t-call="other-template">
    <t t-set="var" t-value="1"/>
</t>
<!-- "var" does not exist here -->

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

<div>
    This template was called with content:
    <t t-raw="0"/>
</div>

被称为:

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

将导致:

<div>
    This template was called with content:
    <em>content</em>
</div>

Python

Exclusive directives(独家指令)

asset bundles(资产包)

"smart records" fields formatting

只有在“智能”记录(browse方法的结果)上执行字段访问(a.b)时,才能使用t-field指令。 它能够根据字段类型自动格式化,并集成在网站的富文本版本中。

t-options可用于自定义字段,最常见的选项是widget,其他选项依赖于字段或窗口小部件。

debugging

t-debug

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

相当于importlib.import_module(“pdb”)。set_trace()

Helpers

Request-based

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

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

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

View-based

比前一个帮助器更深层次的是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

相应的标准库模块

relativedelta

参考模块

keep_query

keep_query帮助函数

Parameters:values -- 要传递给QWeb进行渲染的上下文值

engine(str)-- 用于渲染的Odoo模型的名称,可用于在本地扩展或自定义QWeb(通过创建基于带有更改的ir.qweb的“新”qweb)

Javascript

Exclusive directives(独家指令)

defining templates

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

<templates>
    <t t-name="template-name">
        <!-- template code -->
    </t>
</templates>

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

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

template inheritance

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

模板继承通过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的上下文节点:

append

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

prepend

节点的主体被添加到上下文节点(在上下文节点的第一个子节点之前插入)

before

节点的主体插入到上下文节点之前

after

节点的主体紧接在上下文节点之后插入

inner

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

replace

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

No operation(无操作)

如果没有指定t-operation,模板体将被解释为javascript代码,并以上下文节点作为this的形式执行

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

debugging

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代码。 采用context参数,该参数是t-js主体中渲染上下文可用的名称

<t t-set="foo" t-value="42"/>
<t t-js="ctx">
    console.log("Foo is", ctx.foo);
</t>

Helpers

core.qweb

(core是web.core模块)QWeb2.Engine()的一个实例,其中加载了所有模块定义的模板文件,并引用了标准辅助对象_(下划线),_ t(转换函数)和JSON。

core.qweb.render可用于轻松呈现基本模块模板

API

class QWeb2.Engine()

QWeb“渲染器”处理QWeb的大部分逻辑(加载,解析,编译和渲染模板)。

OpenERP Web为核心模块中的用户实例化一个,并将其导出到core.qweb。 它还将各种模块的所有模板文件加载到该QWeb实例中。

QWeb2.Engine()也可用作“模板命名空间”。

QWeb2.Engine.render(template[, context])

使用context(如果提供)将先前加载的模板呈现给String,以查找在模板呈现期间访问的变量(例如,要显示的字符串)。

Arguments:

template(String)-- 要呈现的模板的名称

context (Object)-- 用于模板渲染的基本命名空间

Returns:String

引擎公开了另一种在某些情况下可能有用的方法(例如,如果你需要一个单独的模板命名空间,在OpenERP Web中,看板视图可以得到他们自己的QWeb2.Engine()实例,这样他们的模板就不会与更一般的碰撞“ 模块“模板”:

QWeb2.Engine.add_template(templates)

在QWeb实例中加载模板文件(模板集合)。 模板可以指定为:

An XML string

QWeb将尝试将其解析为XML文档,然后加载它。

A URL

QWeb将尝试下载URL内容,然后加载生成的XML字符串。

A Document or Node

QWeb将遍历文档的第一级(提供的根的子节点)并加载任何命名的模板或模板覆盖。




QWeb2.Engine()还公开了行为定制的各种属性:

QWeb2.Engine.prefix

用于在解析期间识别指令的前缀。 一个字符串。 默认情况下,t

QWeb2.Engine.debug

将引擎置于“调试模式”的布尔标志。 通常,QWeb会拦截模板执行期间引发的任何错误。 在调试模式下,它会在不拦截所有异常的情况下通过。

QWeb2.Engine.jQuery

模板继承处理期间使用的jQuery实例。 默认为window.jQuery

QWeb2.Engine.preprocess_node

一个功能。 如果存在,则在将每个DOM节点编译为模板代码之前调用。 在OpenERP Web中,这用于自动翻译模板中的文本内容和一些属性。 默认为null

  • [1]它与Genshi类似,尽管它不使用(并且不支持)XML命名空间
  • [2]虽然它使用了一些其他的,无论是出于历史原因还是因为它们更适合用例。 Odoo 9.0仍然依赖于Jinja和Mako。
posted @ 2018-12-18 22:36  苦苦思索的吃瓜群众  阅读(1067)  评论(0编辑  收藏  举报