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

模板指令指定的XML属性的前缀 t-,例如t-if 为条件,与元素和其他属性被直接渲染。

为了避免元素渲染,占位符元素<t>也可用,它执行指令,但本身并不会产生任何输出:

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

结果如下:

<p>Test</p>

如果condition 是 true:

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

则结果如下:

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

数据输出

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

esc 获取表达式,计算并打印内容:

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

用设置为42的值value来渲染:

<p>42</p>

还有一个输出指令raw,它的行为与esc相同,但HTML没有转义输出。它可以显示分别标记有用(例如功能)或已消毒的用户提供的标记。

条件

QWeb有一个条件指令if, 它评估作为属性值的表达式:

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

如果条件为true,则渲染元素:

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

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

<div>
</div>

条件呈现适用于指令的承载者,它不一定是<t>

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

将给出与前面示例相同的结果

附加条件分支指令 t-elif 和t-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>

循环

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

<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而不包含提供证书区间的数组上)。

除了通过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),要求迭代(如数组)大小是可用的

$as_parity

要么是"even" 要么是 "odd",当前迭代循环的奇偶性

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

属性

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

如果参数是一个映射,每个(key,value)对生成一个新属性及其值:

<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 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指令在外部可见的问题。或者,在调用子模板之前,将对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

专用指令

资产包

“智能记录”字段格式化

t-field 指令只能用于当执行在一个“聪明”记录(browsemethod方法返回结果)上的字段访问 (a.b)  。它能够自动基于字段类型进行格式化,并集成了网站富文本编辑。

t-options可使用自定义字段,最常用的选项是widget,其他选项字段或控件的依赖

调试

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

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

quote_plus

url编码实用函数

json

相应的标准库模块

time

相应的标准库模块

datetime

相应的标准库模块

relativedelta

详见模版

keep_query

keep_query 帮助这函数

参数

  • values -- 上下文值传递给QWeb渲染
  • engine (str) -- 用于渲染的Odoo模型名称,可以用来扩展或自定义本地的QWeb (通过创建一个“新的”基于变化ir.qweb的qweb)

Javascript

专用指令

定义模板

t-name 指令只能放在模板文件的顶部(直接将其指向文档根):

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

它不需要其他参数,但可以与<t>元素或其他元素一起使用。如果有一个<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 指令应用:

append

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

prepend

节点的主体被附加到上下文节点的头部 (在上下文节点的第一个子节点之前)

before

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

after

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

inner

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

replace

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

无操作

如果没有指定t-operation ,模板体被解释为JavaScript代码,并使用作为this的上下文节点执行

警告

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

调试

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>

帮助者

core.qweb

(核心是 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(如果提供)查找模板呈现期间访问的变量(例如要显示的字符串)

参数

  • template (String) -- 要呈现的模板的名称
  • context (Object) -- 用于模板呈现的基本命名空间

返回

字符串

引擎暴露出其他的方法,在某些情况下可能是有用的 (如果你需要一个单独的模板的命名空间,在OpenERP Web中,看板视图得到自己的 QWeb2.Engine()实例,因此它们的模板不会和更一般的“模块”模板相抵触):

QWeb2.Engine.add_template(templates)

加载一个QWeb实例的模板文件(模板集)。模板可以指定为:

An XML string

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

A URL

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

Document or Node

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

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

QWeb2.Engine.prefix

在解析过程中用来识别指令的前缀。一个字符串。默认情况下, t

QWeb2.Engine.debug

布尔标志将引擎置于“调试模式”。通常,QWeb截取任何模板时执行抛出错误。在调试模式下,所有异常都会在不拦截的情况下进行

QWeb2.Engine.jQuery

模板继承过程中使用的jQuery实例。默认值为window.jQuery

QWeb2.Engine.preprocess_node

一个 Function。 如果存在,在编译每个DOM节点到模板代码之前调用。在OpenERP Web中,这是用来自动翻译的文字内容和模板中的一些属性。默认值为 null

[1] 它和 Genshi很相似, 尽管它不使用(也不支持)XML名称空间

[2] 虽然它使用了一些其他的,或者是出于历史原因,或者因为它们更适合于用例。Odoo 9.0 仍然依赖于Jinja 和Mako.

ps:有翻译不当之处,欢迎留言指正。

原文地址:https://www.odoo.com/documentation/10.0/reference/qweb.html

odoo10参考系列--QWeb相关推荐

  1. Odoo10参考系列--QWeb报表

    报表是写在HTML / QWeb中,像Odoo中的所有普通视图.你可以使用普通QWeb 流程控制工具.PDF的渲染是通过wkhtmltopdf执行的. 如果要在某个模型上创建报表,则需要定义该报表和它 ...

  2. odoo10参考系列--ORM API 二(新旧API兼容性、模型参考和方法修饰符)

    新API与旧API的兼容性 现在的Odoo是从就的(不规律的)API过渡来的,它可能需要从一个手动桥接到另一个手动桥接: RPC层(XML-RPC和RPC)是在旧的API的形式表达,表达的纯粹的方法在 ...

  3. odoo10参考系列--ORM API 一(记录集、环境、通用方法和创建模型)

    记录集 版本8.0中新东西: 这个在Odoo8.0中新加的API的页面文档应该是不断向前发展的主要开发API.同时它还提供了关于移植或桥接版本7和更早版本的"旧API"的信息,但没 ...

  4. Odoo10参考系列--Odoo指导方针

    本文介绍了新版Odoo编码指南.那些旨在提高代码的质量 (例如更好的可读性)和Odoo应用程序.实际上,适当的代码简化了维护.调试,降低了复杂性,提高了可靠性. 这些指导原则应适用于每一个新的模块和新 ...

  5. Odoo10参考系列--混合而有用的类

    Odoo实现了一些有用的类和混合,使您可以轻松地在对象上添加常用的行为.本指南将详细介绍其中的大部分内容,包括示例和用例. 消息特征 消息集成 基本消息系统 将消息功能集成到模型中非常容易.简单地继承 ...

  6. odoo10参考系列--网络控制器(Web Controllers)

    路由 odoo.http.route(route=None, **kw) 标记装饰方法作为请求处理程序的装饰程序.该方法必须是Controller的一个子类的一部分. 参数 route -- 字符串或 ...

  7. Odoo10参考系列--翻译模块

    导出可翻译的条款 在你的模块的一些条款是作为一个结果的"隐式翻译",即使你没有对翻译做任何具体的工作,你可以导出你的模块的可译性条款和可以找到进行翻译工作的内容. 翻译导出通过管理 ...

  8. odoo10参考系列--命令行接口:odoo-bin

    运行服务器 -d <database>, --database <database> 安装或更新模块时使用的数据库 -i <modules>, --init < ...

  9. odoo10参考系列--视图三(其他高级视图)

    图表 图表视图用于在多个记录或记录组上可视化聚合视图.它的根元素是<graph> ,可以有以下属性: type 使用bar (默认的), pie 和line三个中的一个图表类型 stack ...

最新文章

  1. Ookla speedtest网速测试算法实现
  2. 【Tomcat】Tomcat性能分析
  3. php大负荷,web大负载优化收集------php-fpm参数优化
  4. java当前时间推前三个月_获取当前时间的前三个月 java
  5. Apollo进阶课程㊳丨Apollo平台的快速入门
  6. 如何分析网站日志文件
  7. 简述机器指令与微指令之间的关系_《计算机组成原理》试卷B与参考答案
  8. Java数据库连接详解
  9. UE4下载与存储图片
  10. 并行计算圆周率 c语言,并行计算:圆周率计算
  11. 你真的会调整后视镜吗?正确调整的四个步骤!
  12. 【C++】数字的组合排列情况
  13. 一款集成微信小助手的mac微信最新版!支持发朋友圈!
  14. UGI九宫格sliced显示问题
  15. sci国外期刊投稿过程(已完结)
  16. 纯前端实现人体抠图背景融合-调用Face++抠像接口API实现人像抠图
  17. 光纤布拉格光栅(FBG)笔记【1】:波导结构和布拉格波长推导
  18. facebook聊单?SaleSmatly来助力
  19. javascript获取本周、本月、本季度、本年时间
  20. 《碟中谍5》背后的生物识别技术大比拼

热门文章

  1. 横幅新年促销海报PSD模板,拯救年底节日忙
  2. UI素材实用模板|2.5D等距风格插画专辑
  3. UI设计实用素材|数据可视化UX套件
  4. 实用素材|UI设计师需要的输入框和表单
  5. 淘宝京东卖家可以用到的小工具和素材资源网站
  6. ajax 验证成功 转跳,利用ajax实现登录:验证完用户信息后如何保存用户信息并实现跳转...
  7. 宁波送餐机器人_重磅合作丨擎朗送餐机器人进驻外婆家,让等餐顾客不再流失...
  8. C++static类静态成员函数及变量解析
  9. Seastar:多核机器上编写高效复杂的服务器应用程序的 C++ 库
  10. #include_next