Documente Academic
Documente Profesional
Documente Cultură
master
1 contributor
Raw Blame
<div>
<span t-if="somecondition">Some string</span>
<ul t-else="">
<li t-foreach="messages" t-as="message">
<t t-esc="message"/>
</li>
</ul>
</div>
Template directives are specified as XML attributes prefixed with t- , for instance t-if
for conditionals, with elements and other attributes being rendered directly.
We present in this section the templating language, including its Owl specific
extensions.
Directives
For reference, here is a list of all standard QWeb directives:
Name Description
Name Description
Reference
White Spaces
White spaces in a template are handled in a special way:
Root Nodes
For many reasons, Owl QWeb templates should have a single root node. More
precisely, the result of a template rendering should have a single root node:
Extra root nodes will actually be ignored (even though they will be rendered in
memory).
Note: this does not apply to subtemplates (see the t-call directive). In that case, they
will be inlined in the main template, and can actually have many root nodes.
Expression Evaluation
QWeb expressions are strings that will be processed at compile time. Each variable in
the javascript expression will be replaced with a lookup in the context (so, the
component). For example, a + b.c(d) will be converted into:
context["a"] + context["b"].c(context["d"]);
is valid, and will read the user object from the context, and call the today
function.
3. it can use a few special operators to avoid using symbols such as < , > , & or | .
This is useful to make sure that we still write valid XML.
and &&
or ||
gt >
gte >=
lt <
lte <=
So, one can write this:
Outputting Data
The t-esc directive is necessary whenever you want to add a dynamic text expression
in a template. The text is escaped to avoid security issues.
<p><t t-esc="value"/></p>
rendered with the value value set to 42 in the rendering context yields:
<p>42</p>
The t-raw directive is almost the same as t-esc , but without the escaping. This is
mostly useful to inject a raw html string somewhere. Obviously, this is unsafe to do in
general, and should only be used for strings known to be safe.
<p><t t-raw="value"/></p>
rendered with the value value set to <span>foo</span> in the rendering context
yields:
<p><span>foo</span></p>
Note that since the content of the expression is not known beforehand, the t-raw
directive has to parse the html (and convert it to a virtual dom structure) for each
rendering. So, it will be much slower than a regular template. It is therefore advised to
limit the use of t-raw whenever possible.
Setting Variables
QWeb allows creating variables from within the template, to memoize a computation
(to use it multiple times), give a piece of data a clearer name, ...
This is done via the t-set directive, which takes the name of the variable to create. The
value to set can be provided in two ways:
1. a t-value attribute containing an expression, and the result of its evaluation will
be set:
will print 3 . Note that the evaluation is done at rendering time, not at compilte
time.
2. if there is no t-value attribute, the node’s body is saved and its value is set as the
variable’s value:
<t t-set="foo">
<li>ok</li>
</t>
<t t-esc="foo"/>
The t-set directive acts like a regular variable in most programming language. It is
lexically scoped (inner nodes are sub scopes), can be shadowed, ...
Conditionals
The t-if directive is useful to conditionally render something. It evaluates the
expression given as attribute value, and then acts accordingly.
<div>
<t t-if="condition">
<p>ok</p>
</t>
</div>
The element is rendered if the condition (evaluated with the current rendering context)
is true:
<div>
<p>ok</p>
</div>
The conditional rendering applies to the bearer of the directive, which does not have to
be <t> :
<div>
<p t-if="condition">ok</p>
</div>
Extra conditional branching directives t-elif and t-else are also available:
<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>
Dynamic Attributes
One can use the t-att- directive to add dynamic attributes. Its main use is to evaluate
an expression (at rendering time) and bind an attribute to its result:
<div t-att="{'a': 1, 'b': 2}"/> <!-- result: <div a="1" b="2"></div> -->
Loops
QWeb has an iteration directive t-foreach which take an expression returning the
collection to iterate on, and a second parameter t-as providing the name to use for
the current item of the iteration:
<p>1</p>
<p>2</p>
<p>3</p>
Like conditions, t-foreach applies to the element bearing the directive’s attribute, and
t-foreach can iterate on an array (the current item will be the current value) or an
object (the current item will be the current key).
In addition to the name passed via t-as, t-foreach provides a few other variables for
various data points (note: $as will be replaced with the name passed to t-as ):
$as_value : the current iteration value, identical to $as for lists and integers, but
for objects, it provides the value (where $as provides the key)
$as_index : the current iteration index (the first item of the iteration has index 0)
$as_first : whether the current item is the first of the iteration (equivalent to
$as_index == 0 )
$as_last : whether the current item is the last of the iteration (equivalent to
$as_index + 1 == $as_size ), requires the iteratee’s size be available
These extra variables provided and all new variables created into the t-foreach are
only available in the scope of the t-foreach . If the variable exists outside the context
of the t-foreach , the value is copied at the end of the foreach into the global context.
Even though Owl tries to be as declarative as possible, the DOM does not fully expose
its state declaratively in the DOM tree. For example, the scrolling state, the current user
selection, the focused element or the state of an input are not set as attribute in the
DOM tree. This is why we use a virtual dom algorithm to keep the actual DOM node as
much as possible.
However, in some situations, this is not enough, and we need to help Owl decide if an
element is actually the same, or is a different element with the same properties.
Consider the following situation: we have a list of two items [{text: "a"}, {text:
"b"}] and we render them in this template:
The result will be two <p> tags with text a and b . Now, if we swap them, and
rerender the template, Owl needs to know what the intent is:
This might look trivial, but it actually matters. These two possibilities lead to different
results in some cases. For example, if the user selected the text of the first p , swapping
them will keep the selection while updating the text content will not.
There are many other cases where this is important: input tags with their value, css
classes and animations, scroll position...
So, the t-key directive is used to give an identity to an element. It allows Owl to
understand if different elements of a list are actually different or not.
The above example could be modified by adding an ID: [{id: 1, text: "a"}, {id: 2,
text: "b"}] . Then, the template could look like this:
The t-key directive is useful for lists ( t-foreach ). A key should be a unique number or
string (objects will not work: they will be cast to the "[object Object]" string, which is
obviously not unique).
Also, the key can be set on a t tag or on its children. The following variations are all
equivalent:
If there is no t-key directive, Owl will use the index as a default key.
<div t-name="other-template">
<p><t t-value="var"/></p>
</div>
<div t-name="main-template">
<t t-set="var" t-value="owl"/>
<t t-call="other-template"/>
</div>
will be rendered as <div><p>owl</p></div> . This example shows that the sub template
is rendered with the execution context of the parent. The sub template is actually
inlined in the main template, but in a sub scope: variables defined in the sub template
do not escape.
Sometimes, one might want to pass information to the sub template. In that case, the
content of the body of the t-call directive is available as a special magic variable 0 :
<t t-name="other-template">
This template was called with content:
<t t-raw="0"/>
</t>
<div t-name="main-template">
<t t-call="other-template">
<em>content</em>
</t>
</div>
will result in :
<div>
This template was called with content:
<em>content</em>
</div>
<t t-call="other-template">
<t t-set="var" t-value="1"/>
</t>
<!-- "var" does not exist here -->
Translations
By default, QWeb specify that templates should be translated. If this behaviour is not
wanted, there is a t-translation directive which can turn off translations (if it is set to
the off value), with the following rules:
translating text nodes can be disabled with the special attribute t-translation , if
its value is off .
See here for more information on how to setup a translate function in Owl QWeb.
Debugging
The javascript QWeb implementation provides two useful debugging directives:
<t t-if="a_test">
<t t-debug=""/>
</t>
t-log takes an expression parameter, evaluates the expression during rendering and
logs its result with console.log: