QWeb

QWeb

QWeb是一個基於xml的模板引擎,用於生成HTML片斷和頁面,模板指令是寫在xml標籤中的以t-開頭的屬性,好比t-if
若是要讓一個標籤不被渲染,能夠採用t來包裹,這樣會執行它裏面的命令可是不產生任何輸出javascript

<t t-if="condition">
    <p>Test</p>
</t>
#condtition爲true時上述代碼會輸出:<p>Test</p>
<div t-if="condition">
    <p>Test</p>
</div>
#condtition爲true時上述代碼會輸出:
<div>
    <p>Test</p>
</div>

數據輸出

Qweb有一個自動過濾xss和html的輸出命令esc,它接受一個表達式,解析變輸出結果:css

<p><t t-esc="value"/></p>
#當value值爲42時輸出結果:
<p>42</p>

還有一個raw參數與esc相似,但不過濾html,用於顯示處理好的html內容
html

條件語句

qweb有一個if條件判斷指令,會自動解析其對應的屬性值裏的表達式:java

<div>
    <t t-if="condition">
        <p>ok</p>
    </t>
</div>
#當condition是true的時候解析成:
<div>
    <p>ok</p>
</div>
#condition爲false的時候解析成
<div>
</div>
#也可用下面的方法實現同樣的功能
<div>
    <p t-if="condition">ok</p>
</div>

另外,t-elift-else可用於添加條件分支node

<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有一個指令用於循環處理,t-foreach用來指定須要循環處理的數據,t-as提供的是在後面用於表明當前項目的變量名:python

<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>
#也可用下面的方法實現同樣的功能
<p t-foreach="[1, 2, 3]" t-as="i">
    <t t-esc="i"/>
</p>

foreach可用於數組(當前項目便是值)、映射表(當前項目是key)、整形數字(至關於0-X的數組)jquery

* $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 - 當前項目是奇數個仍是偶數
* $as_even - 當前項目索引是否爲奇數
* $as_odd - 當前項目索引是否爲偶數

上述參數只在foreach裏面可用,但可在循環的最後複製到全局環境中web

<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-attr來實現,有三種形式:數據庫

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

設置變量

qweb容許在模板內設置變量(用於記住一個計算結果、或爲數據定義一個更明確的名字)
使用t-set來實現,它的值就是設置的變量名json

  • 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自動輸義了

調用子模板

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外其餘位置會可見。在t-call內設置的內容會在調用子模板時先執行並更新到當前環境

<t t-call="other-template">
    <t t-set="var" t-value="1"/>
</t>

t-call內包含的內容能夠經過一個0的魔術變量來傳遞給被調用的模板:

#other-template
<div>
    This template was called with content:
    <t t-raw="0"/>
</div>
#main
<t t-call="other-template">
    <em>content</em>
</t>
#output
<div>
    This template was called with content:
    <em>content</em>
</div>

Python

專用指令:

自動格式化記錄

  • t-field只能用於格式化記錄字段(從browe函數獲取到的),能夠根據字段類型自動匹配格式;
  • t-options只能用於自定義字段,最經常使用的是widget,其餘的選項都是field-xxwidget-xx

    調試器(t-debug)

    經過PDB 的set_trace 來進行調試,接收的參數須要是模塊名字,set_trace()會在該模塊上調用
    <t t-debug="pdb"/>至關於:importlib.import_module("pdb").set_trace()

    Helpers

    基於請求的Helper

    python端通常是在controller裏使用qweb,這樣能夠直接調用odoo.http.HttpRequest.render()來渲染保存在數據庫中的模板
response = http.request.render('my-template', {
    'context_value': 42
})
#會直接從controller裏返回一個響應對象

基於視圖的Helper

比上面的更深層次的helper是在ir.ui.view:中的render方法

  • render(cr, uid, id[, values][, engine='ir.qweb][, context])

    經過view的數據庫id來渲染一個qweb視圖模板,模板在ir.ui.view記錄會自動加載,它會爲渲染環境設置一系列默認值
  • request - 當前WebRequest對象
  • debug - 當前請求是不是debug模式
  • quote_plus - 是否進行url encode轉義
  • json - 相關的標準庫
  • time - 相關的標準庫
  • datetime - 相關的標準庫
  • relativedelta - model的時間處理屬性
  • keep_query - 一個keep_query函數,參數1:values-傳遞給qweb的上下文環境,參數2:engine (str) 用於qweb渲染的odoo模型名

    API

    能夠直接使用ir.qweb模型來繼承、擴展他的功能

    Javascript

    專用指令

  • 定義模板

    t-name只能放在模板文件的最外面,離template標籤最近的地方
<templates>
    <t t-name="template-name">
        <!-- template code -->
    </t>
</templates>

它沒有其餘參數,但可使用一個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 - 新節點內容直接替換原節點

    若是沒有指定operation,那麼模板內容會被解析成javascript節點,並將context節點設置爲this

    調試

    qweb的javascript提供多種調試工具

    t-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參數,將當前的環境傳給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()實例,在這個實例中全部模塊相關模板文件所有有加載,並且可以使用_(underscore方法), _t(翻譯方法) 和 JSON
core.qweb.render 能夠用於渲染基本模塊的模板

API

class QWeb2.Engine()

QWeb渲染器,處理qweb的大部分邏輯如加載、解析、編譯、渲染
odoo在core模塊中將user實例化,並輸出到core.qweb,同時將全部模板文件加載到qweb實例中
一個 QWeb2.Engine()同時也能夠當成一個命名空間來看待

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

    將一個模板渲染成字符串,使用context來查找渲染時所遇到的變量

    參數:1.template (String) - 須要渲染的模板名
    2.context (Object) - 渲染時須要用到的命名空間

QWeb2.Engine.add_template(templates)

這個方法在某些狀況下比較有用,用於本身定義一個命名空間並得到單獨的 QWeb2.Engine()實例,這樣不要擔憂與其餘模塊衝突。

該方法加載指定的模板,參數能夠是如下幾種:
1.XML字符串 -- Qweb會將它解析成xml文檔並加載
2.URL -- Qweb會下載對應的url內容,並加載得到的xml字符串
3.Document 或 Node -- qweb會將全部第一級的子節點過濾一遍,並加載命名爲template或從template繼承的部分

QWeb2.Engine.prefix

在解析的時候用來識別指令的前綴,默認是t

QWeb2.Engine.debug

布爾型標誌表示引擎是否使用調試模式,默認狀況下,qweb會把模板執行過程當中產生的錯誤攔截,在調試模式下,全部異常都會被保留

QWeb2.Engine.jQuery

在模板繼承處理時所使用的jQuery實例,默認是window.jQuery

QWeb2.Engine.preprocess_node

一個方法,當它出現時會在編譯dom節點和template節點前調用,通常用於自動模板中的翻譯文本內容或屬性,默認是null

相關文章
相關標籤/搜索