天天看點

odoo10參考系列--QWeb

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

 指令隻能用于當執行在一個“聰明”記錄(

browse

method方法傳回結果)上的字段通路 (

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

繼續閱讀