QWeb模板?

QWeb是Odoo[#othertemplates]_使用的主要模板引擎。它是一個XML模板引擎1,主要用于生成HTML_片段和頁面。

模板指令以帶有 t- 前綴的 XML 屬性的形式指定,例如 條件語句 中的 t-if ,而元素和其他屬性則直接呈現。

為了避免元素渲染,還提供了一個占位符元素 <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>

數據輸出?

QWeb的輸出指令“out”將自動對其輸入進行HTML轉義,限制了在顯示用戶提供的內容時的XSS_風險。

out 接受一個表達式,對其進行求值并將結果注入到文檔中:

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

使用值 value 設置為 42 渲染的結果為:

<p>42</p>

更多高級主題(例如注入原始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()">Happy birthday!</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-out="i"/></p>
</t>

將被渲染為:

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

與條件類似, foreach 應用于帶有指令屬性的元素,并且

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

與前一個示例等效。

foreach 可以迭代數組(當前項將是當前值)或映射(當前項將是當前鍵)。迭代整數(相當于在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 ),需要迭代對象的大小已知。

$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 (屬性)指令完成的,該指令有三種不同的形式:

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>

小技巧

有兩種等效的格式字符串語法: "plain_text {{code}}" (也稱為 jinja 風格)和 "plain_text #{code}" (也稱為 ruby 風格)。

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

上述調用將呈現為 <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-out="0"/>
</div>

被這樣調用:

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

將導致:

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

高級輸出?

默認情況下, out 應該對需要轉義的內容進行 HTML 轉義,以保護系統免受 XSS 攻擊。

不需要轉義的內容將原樣注入文檔中,并可能成為文檔實際標記的一部分。

跨平臺的唯一“安全”內容是 t-call 輸出或者使用帶有“body”的 t-set (而不是 t-valuet-valuef )。

Python?

通常情況下,您不必過于關心:對于需要生成“安全”內容的API,應自動生成,事情應該透明地運行。

對于需要更清晰的情況,以下 API 輸出安全內容,這些內容默認情況下不會在注入模板時被重新轉義:

  • HTML字段 。

  • html_escape()markupsafe.escape() (它們是別名,不會出現雙重轉義的風險)。

  • html_sanitize() 。

  • markupsafe.Markup 。

    警告

    markupsafe.Markup 是一個不安全的 API,它是一個 斷言 ,表示您希望內容是標記安全的,但不能保證,應謹慎使用。

  • to_text() 不會將內容標記為安全的,但不會從安全內容中刪除該信息。

使用 Markup 創建安全內容?

參見官方文檔以了解詳細解釋,但 Markup 的最大優點是它是一種非常豐富的類型,可以重載 str 操作以 自動轉義參數 。

這意味著,通過在字符串文字上使用 Markup 并“格式化”用戶提供的(因此可能不安全的)內容,可以輕松創建 安全的 HTML 片段:

>>> Markup('<em>Hello</em> ') + '<foo>'
Markup('<em>Hello</em> &lt;foo&gt;')
>>> Markup('<em>Hello</em> %s') % '<foo>'
Markup('<em>Hello</em> &lt;foo&gt;')

雖然這是一件非常好的事情,但請注意,有時候效果可能會很奇怪:

>>> Markup('<a>').replace('>', 'x')
Markup('<a>')
>>> Markup('<a>').replace(Markup('>'), 'x')
Markup('<ax')
>>> Markup('<a&gt;').replace('>', 'x')
Markup('<ax')
>>> Markup('<a&gt;').replace('>', '&')
Markup('<a&amp;')

小技巧

大多數內容安全的API實際上返回一個 Markup ,具有所有相關含義。

JavaScript?

警告

由于缺乏運算符重載, :js Markup 類型比 Markup 類型更加受限。

因此,它也不會覆蓋方法,任何涉及到 :js Markup 的操作都會返回一個普通的 :js String (實際上甚至不是那樣,而是一個“原始字符串”)。

這意味著回退是安全的,但是在使用 :js Markup 對象時很容易觸發雙重轉義。

強制雙重轉義?

如果內容被標記為安全的,但由于某些原因仍需要進行轉義(例如打印HTML字段的標記),則可以將其轉換回普通字符串以“去除”安全標志,例如在Python中使用 str(content) ,在Javascript中使用 String(content) 。

注解

因為 Markup 類型比 :js Markup 更豐富,一些操作會從 :js Markup 中剝離安全信息,但不會從 Markup 中剝離,例如在 Python 中進行字符串連接( '' + content )將導致 Markup ,而另一個操作數已經被正確轉義,而在 Javascript 中將產生一個 :js String ,在連接之前另一個操作數沒有被轉義。

已棄用的輸出指令?

esc

escout 的別名,最初用于對輸入進行 HTML 轉義。目前尚未正式棄用,因為 outesc 之間唯一的區別是后者有點不清晰/不正確。

raw

一個永遠不會轉義其內容的 out 版本。無論內容是否安全,都會按原樣發出。

15.0 版后已移除: 使用 markupsafe.Markup 值替代 out 。

由于隨著生成內容的代碼的演變,很難追蹤它將用于標記,從而導致更復雜的審查和更危險的失誤,因此 t-raw 已被棄用。

Python?

獨占指令?

資源包?

“智能記錄”字段格式化?

只有在對“智能”記錄( browse 方法的結果)執行字段訪問( a.b )時,才能使用“ t-field ”指令。它能夠根據字段類型自動格式化,并集成在網站的富文本編輯中。

t-options 可用于自定義字段,最常見的選項是 widget ,其他選項取決于字段或小部件。

調試?

t-debug

使用 PDB 的 set_trace API 調用調試器。參數應該是一個模塊的名稱,在該模塊上調用 set_trace 方法:

<t t-debug="pdb"/>

等同于 importlib.import_module("pdb").set_trace()

渲染緩存:?

t-cache="key_cache" 標簽用于在渲染時緩存模板的一部分。每個子指令只會在第一次渲染時調用。這意味著在渲染這些子指令期間執行的 SQL 查詢也只會執行一次。

t-nocache="documentation" 標簽用于每次渲染模板的部分。內容只能使用根值。

何時何地使用 t-cache ??

該指令用于加速渲染,通過緩存最終文檔的部分內容,可以避免對數據庫的查詢。但是,應該謹慎使用 t-cache ,因為它會不可避免地使模板變得復雜(例如,它們對 t-set 的理解)。

然而,為了真正節省數據庫查詢,可能需要使用惰性求值的值來渲染模板。如果這些惰性求值的值用于緩存部分,則如果該部分可用于緩存,則不會對其進行求值。

t-cache 指令適用于使用依賴于有限數據量的值的模板部分。我們建議使用分析器(通過激活“ 添加 qweb 指令上下文 ”選項)分析模板的渲染。在控制器中將惰性值傳遞到渲染中,可以讓您使用這些值顯示指令并觸發查詢。

使用這樣的緩存的一個問題是使其對不同的用戶可用(不同的用戶應該以相同的方式呈現緩存的部分)。另一個潛在問題是在必要時使其條目無效。對于后者,應明智地選擇 鍵表達式 。例如,使用記錄集的 write_date 可以使緩存鍵過時,而無需顯式地從緩存中丟棄它。

還應注意到 t-cache 部分中的值是有作用域的。這意味著,如果在模板的這部分中有 t-set 指令,則在其后面呈現的內容可能與沒有 t-cache 指令時不同。

如果在一個 t-cache 中有另一個 t-cache 會怎么樣??

這些部分被緩存。每個部分只包含其渲染對應的字符串。因此,內部的 t-cache 可能會被較少讀取,其緩存鍵不一定會被使用。如果必須這樣做,則可能需要添加一個 t-nocache (在同一節點或父節點上)。

t-nocache 用于什么??

如果您想使用“t-cache”緩存模板的一部分,但是某個小部分必須保持動態并在緩存時進行評估。但是,“t-nocache”中的部分將無法訪問模板的“t-set”值。只有控制器提供的值可在此處訪問。例如,菜單被緩存,因為它始終相同且需要時間來呈現(使用qweb上下文的性能開發工具可讓您進行調查)。但是,在菜單中,我們希望電子商務購物車始終保持最新狀態。因此,有一個“t-nocache”來保持此部分動態。

t-cache 的基礎?

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>

在這種情況下,緩存中可能存在與已返回的每個記錄對應的值(字符串),包括 true 條件和 false 條件。如果一個模塊修改了記錄,修改了 write_date,緩存的值將被丟棄。

t-cache 和作用域值( t-set , t-foreach …)?

t-cache 中的值是有作用域的,這意味著在父節點中有或沒有 t-cache 會導致行為上的變化。請注意,Odoo 使用了大量的模板、 t-call 和視圖繼承。因此,添加一個 t-cache 可能會修改您在編輯時看不到的模板的渲染。( t-foreach 就像是每次迭代的 t-set

示例:

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

將渲染(計數器=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 標簽的內容可用于文檔和解釋為什么添加指令。這些值被限定在 t-nocache 中,這些值僅為根值(由控制器提供和/或調用 ir.qweb_render 方法時提供的值)??梢栽谀0宀糠种袌绦?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>

將渲染(計數器=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> 標簽將始終被呈現。而其余部分則作為緩存中的單個字符串。計數器不會被 t-nocache 之外的 t-set 更新。

t-nocache-* 在緩存中添加一些基本值?

為了能夠使用模板生成的值,可以對它們進行緩存。指令使用 t-nocache- *="expr" ,其中 * `` 是所選值的名稱, ``expr 是 Python 表達式,因此結果將被緩存。緩存的值必須是原始類型。

示例:

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

變量 cached_value 被緩存,使用了 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視圖/模板。模板會自動從 ir.qweb 記錄中加載。

_prepare_environment 方法在渲染上下文中設置了許多默認值。 http_routingwebsite 插件也有它們需要的默認值。您可以使用 minimal_qcontext=False 選項來避免 這個默認值,就像公共方法 render 一樣:

request

當前的 Request 對象(如果有的話)

debug

當前請求(如果有)是否處于 調試 模式

quote_plus

URL編碼實用函數

json

相應的標準庫模塊

time

相應的標準庫模塊

datetime

相應的標準庫模塊

relativedelta

查看模塊

keep_query

keep_query 助手函數

參數
  • values – 傳遞給 QWeb 用于渲染的上下文值

  • engine (str) – 用于渲染的Odoo模型名稱,可用于在本地擴展或自定義QWeb(通過基于 ir.qweb 創建“新”QWeb并進行更改)

render(template_name, values, load, **options)?
load(ref)()

返回 etree 對象,引用

JavaScript?

獨占指令?

定義模板?

t-name 指令只能放置在模板文件的頂層(直接子級到文檔根)::

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

它不需要其他參數,但可以與 <t> 元素或任何其他元素一起使用。對于 <t> 元素, <t> 應該只有一個子元素。

模板名稱是任意字符串,但是當多個模板相關聯(例如稱為子模板)時,通常使用點分隔的名稱來表示層次關系。

模板繼承?

模板繼承用于以下兩種情況:
  • 修改現有模板,例如向模板添加信息

由其他模塊創建。
  • 從給定的父模板創建一個新模板

模板繼承通過使用兩個指令來執行:
  • t-inherit 是要繼承的模板名稱。

  • t-inherit-mode 是繼承的行為方式: 它可以設置為 primary 以從父模板創建新的子模板,或者設置為 extension 以直接修改父模板。

還可以指定可選的 t-name 指令。如果在主模式下使用,它將是新創建的模板的名稱,否則它將作為注釋添加到轉換后的模板中,以幫助追溯繼承關系。

對于繼承本身,更改是使用xpaths指令完成的。請參閱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>

舊繼承機制(已棄用)?

模板繼承是通過 t-extend 指令執行的,該指令以要更改的模板名稱作為參數。

當與 t-name 結合使用時,指令 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

節點的主體用于替換上下文節點本身

attributes

節點的主體應該是任意數量的 attribute 元素,每個元素都有一個 name 屬性和一些文本內容,上下文節點的命名屬性將被設置為指定的值(如果已存在,則被替換,如果不存在,則被添加)

沒有操作

如果沒有指定 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.core 模塊) 一個 :js QWeb2.Engine 實例,加載了所有模塊定義的模板文件,并引用了標準的輔助對象 _ (下劃線)、 _t (翻譯函數)和 JSON。

:js core.qweb.render 可以用于輕松渲染基本模塊模板

API?

class QWeb2.Engine()?

QWeb的“渲染器”處理大部分QWeb的邏輯(加載、解析、編譯和渲染模板)。

Odoo Web 在核心模塊中為用戶實例化一個 QWeb 對象,并將其導出到 core.qweb 。它還將各個模塊的所有模板文件加載到該 QWeb 實例中。

一個 :js QWeb2.Engine 同時也作為一個“模板命名空間”。

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

使用 context (如果提供)將預先加載的模板呈現為字符串,以查找在模板呈現期間訪問的變量(例如要顯示的字符串)。

參數
  • template (String()) – 要渲染的模板名稱

  • context (Object()) – 用于模板渲染的基本命名空間

返回

字符串

引擎還公開了另一個方法,在某些情況下可能會很有用(例如,如果您需要一個單獨的模板命名空間,在Odoo Web中,看板視圖會獲得自己的 :js QWeb2.Engine 實例,因此它們的模板不會與更一般的“模塊”模板發生沖突):

QWeb2.Engine.QWeb2.Engine.add_template(templates)?

在 QWeb 實例中加載一個模板文件(一組模板)。模板可以指定為:

一個 XML 字符串

QWeb 將嘗試將其解析為 XML 文檔,然后加載它。

一個URL

QWeb將嘗試下載URL內容,然后加載生成的XML字符串。

一個 DocumentNode

QWeb將遍歷文檔的第一層(提供的根節點的子節點),并加載任何命名模板或模板覆蓋。

A :js 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?

一個 Function 。如果存在,則在將每個DOM節點編譯為模板代碼之前調用。在Odoo Web中,這用于自動翻譯模板中的文本內容和一些屬性。默認為 null 。

1

它與 Genshi 相似,但它不使用(也不支持) XML 命名空間。

2

盡管出于歷史原因或者因為它們更適合特定的用例,Odoo使用了一些其他的模板引擎。但是Odoo 9.0仍然依賴于Jinja_和Mako。