odoo17 | Qweb模板语法大全

odoo17 | Qweb模板语法大全

QWeb模板

QWeb是odoo中主要使用的模板引擎,它是一个XML模板引擎,主要用于生成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转义,这样在显示用户提供的内容时可以有效限制跨站脚本(XSS)风险。

out指令接受一个表达式,计算其结果并将该结果注入到文档中。

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

在value设置为42的情况下呈现:

<p>42</p>

参见“高级输出”以了解更多高级主题(例如注入原始HTML等内容)。

条件

QWeb提供了一个条件指令t-if,该指令会计算其属性值中给定的表达式:

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

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

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

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

<div>
</div>

条件呈现适用于指令的持有者,该指令的持有者确实如此 不一定是:

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

这将产生与前一个示例相同的结果。

另外还提供了额外的条件分支指令t-elif和t-else。

<div>
    <p t-if="user.birthday == today()">Happy birthday!</p>
    <p t-elif="user.login == 'root'">Wel***e master!</p>
    <p t-else="">Wel***e!</p>
</div>

循环

QWeb提供了一个迭代指令t-foreach,该指令接受一个返回待遍历集合的表达式作为参数,并且需要第二个参数来指定在迭代过程中“当前项”所使用的名称: t-foreach与t-as搭配使用。

<t t-foreach="[1, 2, 3]" t-as="i">
    <p><t t-out="i"/></p>
</t>

将呈现为:

<p>1</p>
<p>2</p>
<p>3</p>

与条件指令类似,t-foreach作用于带有该指令属性的元素上,并且对指定集合进行迭代。


<p t-foreach="[1, 2, 3]" t-as="i">
    <t t-out="i"/>
</p>

这与前面的示例效果相同。

t-foreach可以对数组进行迭代(当前项将是当前值),也可以对映射进行迭代(当前项将是当前键)。虽然仍支持对整数进行迭代(等同于在0(包含)和提供的整数(不包含)之间的数组上迭代),但这一做法已过时并被弃用。

除了通过t-as传递的名称外,t-foreach还为各种数据点提供了几个其他变量。

警告

$as将会被传递给t-as的名称替换。

  • $as_all(已弃用)
    被迭代的对象

注意
此变量仅在 JavaScript QWeb 上可用,而不适用于 python

  • $as_value

    当前迭代值,与 for lists 和 integers 相同, 但对于映射,它提供值(其中提供键) a s as asas

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

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

  • a s f i r s t 当前项是否为迭代中的第一个项(等效于 as_first 当前项是否为迭代中的第一个项(等效于 asfirst当前项是否为迭代中的第一个项(等效于as_index == 0)

  • a s l a s t 当前项是否为迭代的最后一个(等效于),要求迭代对象的大小为可用 as_last 当前项是否为迭代的最后一个(等效于 ),要求迭代对象的大小为 可用 aslast当前项是否为迭代的最后一个(等效于),要求迭代对象的大小为可用as_index + 1 == $as_size

  • $as_parity(已弃用)
    either 或 ,当前迭代轮次的奇偶校验"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_index % 2 === 0) ? 'even' : 'odd' }}">
        <t t-out="item"/>
    </li>
</t>

将会被呈现为:

<li class="row even">1</li>
<li class="row odd">2</li>
<li class="row even">3</li>

提示

在QWeb模板中,有以下格式化字符串的两种等效语法:(也称为Jinja风格)和(也称为Ruby风格)。“plain_text {{code}}”
“plain_text #{code}”

  • t-att属性映射
    如果参数是一个映射(字典),则每个键值对将生成一个新属性及其对应的值:
<div t-att="{'a': 1, 'b': 2}"/>

将被渲染为:

<div a="1" b="2"></div>
  • t-att属性对
    如果参数是一对(元组或包含两个元素的数组),则该对的第一个元素作为属性名,第二个元素作为属性值:
<div t-att="['a', 'b']"/>

将被渲染为:

<div a="b"></div>

设置变量

QWeb允许在模板内部创建变量,用于存储计算结果(以便多次使用)、给数据片段赋予更清晰的名称等。这通过t-set指令完成,该指令接受要创建的变量名。变量的赋值可以通过两种方式提供:

  • 使用t-value属性包含一个表达式,其计算结果将作为变量的值:
<t t-set="foo" t-value="2 + 1"/>
<t t-out="foo"/>

这段代码将会输出3。

  • 如果没有t-value属性,则节点的内容会被渲染并作为变量的值:
<t t-set="foo">
    <li>ok</li>
</t>
<t t-out="foo"/>

调用子模板

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时,可以在指令体中设置变量,这些变量会在调用子模板之前进行评估,并且可以更改本地上下文:

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

t-call指令的主体可以是任意复杂的结构(不仅仅是简单的指令)。它的呈现结果将以魔术变量set0的形式在被调用模板中可用:

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

因此,当这样调用时:

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

将导致:

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

高级输出

默认情况下,通过t-out指令输出的内容会自动进行HTML转义以防止XSS攻击。不需要转义的内容会原样注入文档,并可能成为实际HTML标记的一部分。

唯一跨平台安全的内容包括来自t-call输出的内容以及与t-set一起使用的“body”内容(而非t-valuef)。

Python

通常情况下,您无需过多关注:那些有道理应该生成“安全”内容的API会自动做到这一点,并且事情应当透明地运行。

然而,在某些需要更明确的情况中,以下API会输出默认在注入到模板时不会(重新)转义的安全内容:

  • HTML字段。

    html_escape()escape()(它们是别名,不会有双重转义的风险)。

    markupsafe.escape()

  • html_sanitize()

  • markupsafe.Markup 类及其实例。

警告:
markupsafe.Markup 是一种不安全的API,它表明您希望内容为标记安全的,但实际上无法检查这一点,因此应当小心使用。

  • to_text() 不会将内容标记为安全,但也不会从已安全的内容中剥离安全性信息。

强制双层转义

如果内容被标记为安全,但由于某些原因仍需要转义(例如,要打印HTML字段的原始标记),可以将其转换回普通字符串以“去除”安全标志。在Python中和JavaScript中分别可以这样做:
python

str(content)

javascript

String(content)

这样操作后,即使原本的内容被认为安全而不会被自动转义,在将其转换为普通字符串后,再次注入到模板或其他地方时将会按照常规进行转义处理。

注意:
由于Markup类型比普通字符串更丰富,在一些操作中,Markup类型的某些操作会剥离安全信息,而普通字符串则不会。例如,在Python中使用字符串连接操作(+)会导致其中一个操作数被正确转义后的str类型,而在JavaScript中,+运算符将得到一个未转义前就被连接起来的结果。

废弃的输出指令

  • esc: 是out的一个别名,原本会对其输入进行HTML转义。尚未正式废弃,因为outesc之间的唯一区别在于后者含义不太清晰/不准确。
  • raw: 是out的一个版本,永不转义其内容。无论内容是否安全,都会原样输出。

废弃自15.0版本起:请改用带有markupsafe.Markup值的out

Python

专享指令

资产包

智能记录字段格式化

t-field指令只能在对“智能”记录(方法的结果)执行字段访问(如a.b)时使用。它可以基于字段类型自动格式化,并且与网站的富文本编辑功能集成。

t-options可用于定制字段,最常见的选项是widget,其他选项取决于特定的字段或小部件。

调试

  • t-debug
    t-debug指令的值为空时,会调用内置函数breakpoint(),通常会触发调试器(默认为pdb)。此行为可以通过PYTHONBREAKPOINT环境变量或sys.breakpointhook()进行配置。

渲染缓存:

t-cache="key_cache"标记要在渲染时缓存的模板部分。 每个子指令将仅在第一次渲染期间调用。这意味着 在呈现这些子指令期间超出的 SQL 查询 也只做一次。

t-nocache="documentation"标记每次要渲染的模板部分。 内容只能使用根值。

为什么以及何时使用t-cache?

该指令用于通过缓存最终文档的部分内容来加速渲染,这可能会节省对数据库的查询。然而,应谨慎使用t-cache,因为它不可避免地会使模板变得复杂(例如对其理解造成困难)。

在实际节约数据库查询时,可能需要以惰性求值的方式渲染模板。如果这些惰性值被用在了缓存部分中,在缓存中有这部分内容时,它们将不会被评估。

t-cache指令对于那些使用依赖于有限数据集的值的模板部分非常有用。我们建议通过启用“添加qweb指令上下文”选项分析模板的渲染情况。在控制器中向渲染传递惰性值有助于显示使用这些值的指令,并触发相应的查询。

使用此类缓存的一个关注点是如何使其适用于不同用户(不同的用户应该以相同的方式渲染缓存部分)。另一个潜在问题是适时使缓存失效。为此,应当明智地选择键表达式。例如,使用记录集的write_date可以使得缓存键过期,而无需显式从缓存中移除它。

同时需要注意的是,缓存部分中的值具有作用域限制。这意味着,如果模板这部分包含t-set指令,那么其后的渲染结果可能会与没有t-set指令时有所不同。

如果在t-cache内部还有一个t-cache指令?

这些组件已经被缓存,其中每个仅包含各自渲染后的字符串表示。这样一来,内部的部分很可能访问频率较低,其对应的缓存键也可能不会经常用到。倘若确实存在这样的情况,即内部内容应当独立于外部环境而不受其影响,则你可能需要在同一节点或者其父节点上添加一个t-cachet-nocache标签来禁用这部分内容的缓存功能。

t-nocache是做什么用的?

如果你想使用t-cache缓存模板的一部分,但其中一小部分内容需要保持动态并在缓存时重新计算。然而,在t-cache内的t-nocache部分将无法访问到模板中的变量值。这里仅能访问由控制器提供的值。例如,菜单项总是相同且渲染耗时较长(可以利用性能开发工具配合qweb上下文进行分析),因此将其整体缓存是合理的。但在菜单中,我们希望电商购物车始终显示最新的状态。所以在这里使用了t-nocache来确保这部分内容始终保持动态,并且可以利用t-set指令设置和更新购物车的相关数据。

t-cache的基础

指令允许你存储模板渲染的结果。键表达式(例如 42: t-cache=“42”)会被当作Python表达式进行计算。这个表达式将用于生成缓存键,因此对于同一个模板部分,可以根据不同的键表达式值拥有不同的缓存值(已缓存的渲染部分)。如果键表达式返回一个元组或列表,那么在生成缓存键时会搜索这些内容。如果键表达式返回了一个或多个记录集,那么模型、ID及其对应的write_date(写入日期)将会被用来生成缓存键。

特殊情况:如果键表达式返回了Falsy值(即假值),那么内容将不会被缓存。

示例:

<div t-cache="record,bool(condition)">
    <span t-if="condition" t-field="record.partner_id.name">
    <span t-else="" t-field="record.partner_id" t-options-widget="contact">
</div>

在这种情况下,对于已经根据真条件返回的每条记录以及假条件,缓存中都可能存在相应的值(字符串)。如果某个模块修改了记录,则被修改的记录的write_date会发生变化,此时已缓存的值会被丢弃。

t-cache 与作用域内的值(如 t-set 和 t-foreach)
在t-cache区域内的值具有作用域限制,这意味着是否在其父节点之一上使用了t-cache会改变其行为表现。务必记住,Odoo大量使用了模板和视图继承机制。因此,在某个地方添加一个t-cache可能会修改你在编辑时并未直接看到的其他模板的渲染效果。(这就像在每个迭代中使用的for each循环一样,会影响到范围内的变量状态)

示例:


<div>
    <t t-set="a" t-value="1"/>
    <inside>
        <t t-set="a" t-value="2"/>
        <t t-out="a"/>
    </inside>
    <outside t-out="a"/>

    <t t-set="b" t-value="1"/>
    <inside t-cache="True">
        <t t-set="b" t-value="2"/>
        <t t-out="b"/>
    </inside>
    <outside t-out="b"/>
</div>

将呈现:

<div>
    <inside>2</inside>
    <outside>2</inside>

    <inside>2</inside>
    <outside>1</inside>
</div>

t-nocache的基础

带有t-nocache属性的节点所包含的模板部分不会被缓存。因此,这部分内容是动态的,并且每次都会被系统地重新渲染。然而,在这个区域内可访问的值仅限于由控制器提供的那些值(在调用render方法时)。

示例:

<section>
    <article t-cache="record">
        <title><t t-out="record.name"/> <i t-nocache="">(views: <t t-out="counter"/>)</i></titlle>
        <content t-out="record.description"/>
    </article>
</section>

将呈现 (counter = 1):

<section>
    <article>
        <title>The record name <i>(views: 1)</i></titlle>
        <content>Record description</content>
    </article>
</section>

在此,包含<i>标签的容器部分将始终被渲染。而其他部分作为一个整体字符串存储在缓存中。

t-nocache 与作用域根值(如 t-set 和 t-foreach) t-nocache 标签内的内容可用于文档说明,并解释为何添加此指令。该标签内的值具有局部作用域限制,这些值仅限于根级别的值(由控制器提供的值和/或调用 ir.qweb.render 方法时传递的值)。可以在 t-nocache 标签内的模板部分执行 t-set 操作,但这些设置的变量值不会在其他地方可用。

例:

<section>
    <t t-set="counter" t-value="counter * 10"/>
    <header t-nocache="">
        <t t-set="counter" t-value="counter + 5"/>
        (views: <t t-out="counter"/>)
    </header>
    <article t-cache="record">
        <title><t t-out="record.name"/> <i t-nocache="">(views: <t t-out="counter"/>)</i></titlle>
        <content t-out="record.description"/>
    </article>
    <footer>(views: <t t-out="counter"/>)</footer>
</section>

将呈现 (counter = 1):

<section>
    <header>
        (views: 6)
    </header>
    <article>
        <title>The record name <i>(views: 1)</i></titlle>
        <content>Record description</content>
    </article>
    <footer>(views: 10)</footer>
</section>

在此例中,包含<i>标签的容器部分将始终进行渲染。而其余部分则作为一个单一字符串存储在缓存中。计数器不会因为<i>标签外部的t-set指令更新。

t-nocache-*在缓存中添加一些基元值

为了能够使用模板中生成的值,可以 缓存它们。该指令用作 where is 所选值的名称和 Python 表达式,因此结果将 被缓存。缓存的值必须是基元类型。t-nocache-*=“expr”*expr

例:

<section t-cache="records">
    <article t-foreach="records" t-as="record">
        <header>
            <title t-field="record.get_method_title()"/>
        </header>
        <footer t-nocache="This part has a dynamic counter and must be rendered all the time."
                t-nocache-cached_value="record.get_base_counter()">
            <span t-out="counter + cached_value"/>
        </footer>
    </article>
</section>

该值随着t-cache="records"所缓存的模板部分一起被缓存,并且每次都会添加到局部作用域内的根级变量中。

帮助

基于请求

QWeb Python 端的大多数使用场景是在控制器中(以及HTTP请求期间),在这种情况下,存储在数据库中的模板(作为视图)可以通过调用 odoo.http.HttpRequest.render() 方法轻松地进行渲染。

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

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

基于视图

在之前的辅助方法更深层次上,有ir.qweb对象上的_render方法(使用可迭代的数据集)以及公共模块方法render(不直接使用数据库):

  • _render(id[, values])
    通过数据库ID或外部ID渲染一个QWeb视图/模板。模板会自动从记录中加载。
    _prepare_environment 方法会在渲染环境上下文中设置多个预设的默认值,其中包含了附加组件(addons)及其所需的一些基本默认值。如果你想不采用这些默认值,可以像在公开的方法 http_routing 中那样使用 minimal_qcontext=False 参数来调用渲染函数:

    • request
      当前Request对象(如果有)

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

    • quote_plus
      url 编码实用程序函数

    • json
      对应的标准库模块

    • time
      对应的标准库模块

    • datetime
      对应的标准库模块

    • relativedelta
      relativedelta 是一个来自 Python 的 dateutil 库中的类,用于处理日期和时间的相对偏移量。

    • keep_query
      Helper 函数keep_query

      • 参数
        • values – 传递给 QWeb 进行渲染的上下文值
        • engine (str) – 用于渲染的 Odoo 模型的名称,可以是 用于在本地扩展或自定义 QWeb(通过创建 基于改动的“新”qweb)ir.qweb
  • render(template_name, values, load, **options)

    • load(ref)()
      返回 etree object ref

Javascript

专享指令

定义模板

指令只能被放置在模板文件的顶级(作为文档根元素的直接子元素):t-name

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

该指令不接受其他参数,但可以与元素或其他任何元素一起使用。当与元素结合使用时,应确保<t>元素仅有一个子元素。

模板名称是一个任意字符串,但在多个模板之间存在关联关系(例如调用子模板)时,通常会采用点分隔的方式来命名,以表示层级关系。

模板继承

模板继承用于:
就地更改现有模板,例如向模板添加信息

由其他模块创建。

  • 从给定的父模板创建新模板

模板继承通过使用两个指令来执行:

  • t-inherit这是要从中继承的模板的名称,

-t-inherit-mode 指令决定了继承的行为方式:它可以设置为 primary,以从父模板创建一个新的子模板;或者设置为 extension,以便在原地修改父模板内容。

此外,还可以选择性地指定一个 t-name 指令。在“primary”模式下使用时,它将作为新创建模板的名称;而在其他情况下,它会被添加为转换后模板上的注释,以帮助追溯继承关系。

对于模板本身的继承操作,更改是通过xpath指令完成的。有关所有可用指令的完整列表,请参阅XPath文档。

主要(子)模板继承示例:

<t t-name="child.template" t-inherit="base.template" t-inherit-mode="primary">
    <xpath expr="//ul" position="inside">
        <li>new element</li>
    </xpath>
</t>

扩展继承(就地转换):

<t t-inherit="base.template" t-inherit-mode="extension">
    <xpath expr="//tr[1]" position="after">
        <tr><td>new cell</td></tr>
    </xpath>
</t>

指令接受一个CSS选择器。该选择器应用于扩展的模板,用于选择将指定操作应用到的目标上下文节点:t-jqueryt-operation

  • append:将节点内容追加到目标上下文节点的末尾(即在上下文节点最后一个子节点之后)

  • prepend:将节点内容插入到目标上下文节点之前(即在上下文节点第一个子节点之前)

  • before:将节点内容直接插入到目标上下文节点之前

  • after:将节点内容直接插入到目标上下文节点之后

  • inner:用节点内容替换目标上下文节点的所有子节点

  • replace:使用节点内容替换目标上下文节点自身

  • attributes:节点内容应包含任意数量的元素,每个元素都有一个attributename属性和一些文本内容,目标上下文节点的相应名称属性会被设置为指定的值(如果已存在则替换,否则添加)

  • 无操作
    如果未指定 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
    core 指代模块)web.coreQWeb2.Engine() 的一个实例,其中已经加载了所有由模块定义的模板文件,并且包含了对标准辅助对象(如 underscore)、翻译函数(如 _t)和 JSON 对象的引用。

可以使用 core.qweb.render 来轻松地渲染基本的模块模板。

API

  • class QWeb2.Engine()
    QWeb“渲染器”负责处理QWeb的大部分逻辑,包括加载、解析、编译和渲染模板。
    在Odoo Web中,核心模块为用户实例化了一个QWeb,并将其导出到core.qweb。同时,它还会将各个模块的所有模板文件加载到这个QWeb实例中。
    一个QWeb2.Engine()实例也充当着“模板命名空间”的角色。

    • QWeb2.Engine.QWeb2.Engine.render(template[, context])
      将之前加载的模板渲染成一个字符串,并且在渲染过程中(如果提供的话)使用context来查找模板中访问到的变量(例如要显示的字符串)。

      • 参数
        template (String()) – 要渲染的模板的名称
        context(Object()) – 用于模板的基本命名空间 渲染

      • 返回 String字符串

      该引擎还公开了一个在某些情况下可能有用的其他方法(例如,在Odoo Web中,如果需要一个带有独立模板命名空间的环境,看板视图会获取它们自己的QWeb2.Engine()实例,以避免与更通用的“模块”模板发生冲突):

    • QWeb2.Engine.QWeb2.Engine.add_template(templates)
      在QWeb实例中加载一个模板文件(即一组模板)。这些模板可以以如下形式指定:

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

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

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

    • 一个QWeb2.Engine()还公开了多个属性,用于自定义其行为:

      • QWeb2.Engine.QWeb2.Engine.prefix
        在解析过程中用于识别指令的前缀。类型为字符串,默认值为 .t

      • QWeb2.Engine.QWeb2.Engine.debug
        布尔标志,用于将引擎置于“调试模式”。通常情况下,QWeb会在模板执行期间截获所有引发的错误。而在调试模式下,它不会拦截任何异常,而是让它们直接通过。

      • QWeb2.Engine.QWeb2.Engine.jQuery
        在模板继承处理过程中使用的jQuery实例,默认为 window.jQuery

      • QWeb2.Engine.QWeb2.Engine.preprocess_node
        一个函数。如果存在,则会在将每个DOM节点编译为模板代码之前调用此函数。在Odoo Web中,该函数用于自动翻译模板中的文本内容和某些属性。默认值为 Functionnull

  1. 它在这一点上与Genshi相似,尽管它并不使用(也不支持)XML命名空间。

  2. 虽然它还使用了其他一些模板引擎,要么是因为历史原因,要么是因为它们对于特定用例来说仍然是更好的选择。Odoo 9.0版本仍然依赖于Jinja和Mako这两个模板引擎。

转载请说明出处内容投诉
CSS教程_站长资源网 » odoo17 | Qweb模板语法大全

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买