4 QWeb is the template engine used by the OpenERP Web Client. It is an
5 XML-based templating language, similar to `Genshi
6 <http://en.wikipedia.org/wiki/Genshi_(templating_language)>`_,
7 `Thymeleaf <http://en.wikipedia.org/wiki/Thymeleaf>`_ or `Facelets
8 <http://en.wikipedia.org/wiki/Facelets>`_ with a few peculiarities:
10 * It's implemented fully in javascript and rendered in the browser.
11 * Each template file (XML files) contains multiple templates, where
12 template engine usually have a 1:1 mapping between template files
14 * It has special support in OpenERP Web's
15 :class:`~instance.web.Widget`, though it can be used outside of
16 OpenERP Web (and it's possible to use :class:`~instance.web.Widget`
17 without relying on the QWeb integration).
19 The rationale behind using QWeb instead of a more popular template syntax is
20 that its extension mechanism is very similar to the openerp view inheritance
21 mechanism. Like openerp views a QWeb template is an xml tree and therefore
22 xpath or dom manipulations are easy to performs on it.
24 Here's an example demonstrating most of the basic QWeb features:
29 <div t-name="example_template" t-attf-class="base #{cls}">
30 <h4 t-if="title"><t t-esc="title"/></h4>
32 <li t-foreach="items" t-as="item" t-att-class="item_parity">
33 <t t-call="example_template.sub">
34 <t t-set="arg" t-value="item_value"/>
39 <t t-name="example_template.sub">
42 <t t-foreach="arg.tags" t-as="tag" t-if="tag_index lt 5">
43 <dt><t t-esc="tag"/></dt>
44 <dd><t t-esc="tag_value"/></dd>
50 rendered with the following context:
56 "title": "Random Title",
58 { "name": "foo", "tags": {"bar": "baz", "qux": "quux"} },
59 { "name": "Lorem", "tags": {
62 "consectetur": "adipiscing",
64 "hendrerit": "ullamcorper",
66 "vestibulum": "Lorem",
74 will yield this section of HTML document (reformated for readability):
78 <div class="base foo">
111 While QWeb implements a number of attributes and methods for
112 customization and configuration, only two things are really important
115 .. js:class:: QWeb2.Engine
117 The QWeb "renderer", handles most of QWeb's logic (loading,
118 parsing, compiling and rendering templates).
120 OpenERP Web instantiates one for the user, and sets it to
121 ``instance.web.qweb``. It also loads all the template files of the
122 various modules into that QWeb instance.
124 A :js:class:`QWeb2.Engine` also serves as a "template namespace".
126 .. js:function:: QWeb2.Engine.render(template[, context])
128 Renders a previously loaded template to a String, using
129 ``context`` (if provided) to find the variables accessed
130 during template rendering (e.g. strings to display).
132 :param String template: the name of the template to render
133 :param Object context: the basic namespace to use for template
137 The engine exposes an other method which may be useful in some
138 cases (e.g. if you need a separate template namespace with, in
139 OpenERP Web, Kanban views get their own :js:class:`QWeb2.Engine`
140 instance so their templates don't collide with more general
143 .. js:function:: QWeb2.Engine.add_template(templates)
145 Loads a template file (a collection of templates) in the QWeb
146 instance. The templates can be specified as:
149 QWeb will attempt to parse it to an XML document then load
153 QWeb will attempt to download the URL content, then load
154 the resulting XML string.
156 A ``Document`` or ``Node``
157 QWeb will traverse the first level of the document (the
158 child nodes of the provided root) and load any named
159 template or template override.
161 :type templates: String | Document | Node
163 A :js:class:`QWeb2.Engine` also exposes various attributes for
164 behavior customization:
166 .. js:attribute:: QWeb2.Engine.prefix
168 Prefix used to recognize :ref:`directives <qweb-directives>`
169 during parsing. A string. By default, ``t``.
171 .. js:attribute:: QWeb2.Engine.debug
173 Boolean flag putting the engine in "debug mode". Normally,
174 QWeb intercepts any error raised during template execution. In
175 debug mode, it leaves all exceptions go through without
178 .. js:attribute:: QWeb2.Engine.jQuery
180 The jQuery instance used during :ref:`template inheritance
181 <qweb-directives-inheritance>` processing. Defaults to
184 .. js:attribute:: QWeb2.Engine.preprocess_node
186 A ``Function``. If present, called before compiling each DOM
187 node to template code. In OpenERP Web, this is used to
188 automatically translate text content and some attributes in
189 templates. Defaults to ``null``.
196 A basic QWeb template is nothing more than an XHTML document (as it
197 must be valid XML), which will be output as-is. But the rendering can
198 be customized with bits of logic called "directives". Directives are
199 attributes elements prefixed by :js:attr:`~QWeb2.Engine.prefix` (this
200 document will use the default prefix ``t``, as does OpenERP Web).
202 A directive will usually control or alter the output of the element it
203 is set on. If no suitable element is available, the prefix itself can
204 be used as a "no-operation" element solely for supporting directives
205 (or internal content, which will be rendered). This means:
209 <t>Something something</t>
211 will simply output the string "Something something" (the element
212 itself will be skipped and "unwrapped"):
214 .. code-block:: javascript
216 var e = new QWeb2.Engine();
217 e.add_template('<templates>\
218 <t t-name="test1"><t>Test 1</t></t>\
219 <t t-name="test2"><span>Test 2</span></t>\
221 e.render('test1'); // Test 1
222 e.render('test2'); // <span>Test 2</span>
226 The conventions used in directive descriptions are the following:
228 * directives are described as compound functions, potentially with
229 optional sections. Each section of the function name is an
230 attribute of the element bearing the directive.
232 * a special parameter is ``BODY``, which does not have a name and
233 designates the content of the element.
235 * special parameter types (aside from ``BODY`` which remains
236 untyped) are ``Name``, which designates a valid javascript
237 variable name, ``Expression`` which designates a valid
238 javascript expression, and ``Format`` which designates a
239 Ruby-style format string (a literal string with
240 ``#{Expression}`` inclusions executed and replaced by their
245 ``Expression`` actually supports a few extensions on the
246 javascript syntax: because some syntactic elements of javascript
247 are not compatible with XML and must be escaped, text
248 substitutions are performed from forms which don't need to be
249 escaped. Thus the following "keyword operators" are available in
250 an ``Expression``: ``and`` (maps to ``&&``), ``or`` (maps to
251 ``||``), ``gt`` (maps to ``>``), ``gte`` (maps to ``>=``), ``lt``
252 (maps to ``<``) and ``lte`` (maps to ``<=``).
254 .. _qweb-directives-templates:
259 .. _qweb-directive-name:
261 .. function:: t-name=name
263 :param String name: an arbitrary javascript string. Each template
264 name is unique in a given
265 :js:class:`QWeb2.Engine` instance, defining a
266 new template with an existing name will
267 overwrite the previous one without warning.
269 When multiple templates are related, it is
270 customary to use dotted names as a kind of
271 "namespace" e.g. ``foo`` and ``foo.bar`` which
272 will be used either by ``foo`` or by a
273 sub-widget of the widget used by ``foo``.
275 Templates can only be defined as the children of the document
276 root. The document root's name is irrelevant (it's not checked)
277 but is usually ``<templates>`` for simplicity.
282 <t t-name="template1">
283 <!-- template code -->
287 :ref:`t-name <qweb-directive-name>` can be used on an element with
293 <div t-name="template2">
294 <!-- template code -->
298 which ensures the template has a single root (if a template has
299 multiple roots and is then passed directly to jQuery, odd things
302 .. _qweb-directives-output:
307 .. _qweb-directive-esc:
309 .. function:: t-esc=content
311 :param Expression content:
313 Evaluates, html-escapes and outputs ``content``.
315 .. _qweb-directive-escf:
317 .. function:: t-escf=content
319 :param Format content:
321 Similar to :ref:`t-esc <qweb-directive-esc>` but evaluates a
322 ``Format`` instead of just an expression.
324 .. _qweb-directive-raw:
326 .. function:: t-raw=content
328 :param Expression content:
330 Similar to :ref:`t-esc <qweb-directive-esc>` but does *not*
331 html-escape the result of evaluating ``content``. Should only ever
332 be used for known-secure content, or will be an XSS attack vector.
334 .. _qweb-directive-rawf:
336 .. function:: t-rawf=content
338 :param Format content:
340 ``Format``-based version of :ref:`t-raw <qweb-directive-raw>`.
342 .. _qweb-directive-att:
344 .. function:: t-att=map
346 :param Expression map:
348 Evaluates ``map`` expecting an ``Object`` result, sets each
349 key:value pair as an attribute (and its value) on the holder
354 <span t-att="{foo: 3, bar: 42}"/>
360 <span foo="3" bar="42"/>
362 .. function:: t-att-ATTNAME=value
365 :param Expression value:
367 Evaluates ``value`` and sets it on the attribute ``ATTNAME`` on
370 If ``value``'s result is ``undefined``, suppresses the creation of
373 .. _qweb-directive-attf:
375 .. function:: t-attf-ATTNAME=value
380 Similar to :ref:`t-att-* <qweb-directive-att>` but the value of
381 the attribute is specified via a ``Format`` instead of an
382 expression. Useful for specifying e.g. classes mixing literal
383 classes and computed ones.
385 .. _qweb-directives-flow:
390 .. _qweb-directive-set:
392 .. function:: t-set=name (t-value=value | BODY)
395 :param Expression value:
398 Creates a new binding in the template context. If ``value`` is
399 specified, evaluates it and sets it to the specified
400 ``name``. Otherwise, processes ``BODY`` and uses that instead.
402 .. _qweb-directive-if:
404 .. function:: t-if=condition
406 :param Expression condition:
408 Evaluates ``condition``, suppresses the output of the holder
409 element and its content of the result is falsy.
411 .. _qweb-directive-foreach:
413 .. function:: t-foreach=iterable [t-as=name]
415 :param Expression iterable:
418 Evaluates ``iterable``, iterates on it and evaluates the holder
419 element and its body once per iteration round.
421 If ``name`` is not specified, computes a ``name`` based on
422 ``iterable`` (by replacing non-``Name`` characters by ``_``).
424 If ``iterable`` yields a ``Number``, treats it as a range from 0
425 to that number (excluded).
427 While iterating, :ref:`t-foreach <qweb-directive-foreach>` adds a
428 number of variables in the context:
431 If iterating on an array (or a range), the current value in
432 the iteration. If iterating on an *object*, the current key.
434 The collection being iterated (the array generated for a
437 The current iteration value (current item for an array, value
438 for the current item for an object)
440 The 0-based index of the current iteration round.
442 Whether the current iteration round is the first one.
444 ``"odd"`` if the current iteration round is odd, ``"even"``
445 otherwise. ``0`` is considered even.
447 .. _qweb-directive-call:
449 .. function:: t-call=template [BODY]
451 :param String template:
454 Calls the specified ``template`` and returns its result. If
455 ``BODY`` is specified, it is evaluated *before* calling
456 ``template`` and can be used to specify e.g. parameters. This
457 usage is similar to `call-template with with-param in XSLT
458 <http://zvon.org/xxl/XSLTreference/OutputOverview/xslt_with-param_frame.html>`_.
460 .. _qweb-directives-inheritance:
462 Template Inheritance and Extension
463 ++++++++++++++++++++++++++++++++++
465 .. _qweb-directive-extend:
467 .. function:: t-extend=template BODY
469 :param String template: name of the template to extend
471 Works similarly to OpenERP models: if used on its own, will alter
472 the specified template in-place; if used in conjunction with
473 :ref:`t-name <qweb-directive-name>` will create a new template
474 using the old one as a base.
476 ``BODY`` should be a sequence of :ref:`t-jquery
477 <qweb-directive-jquery>` alteration directives.
481 The inheritance in the second form is *static*: the parent
482 template is copied and transformed when :ref:`t-extend
483 <qweb-directive-extend>` is called. If it is altered later (by
484 a :ref:`t-extend <qweb-directive-extend>` without a
485 :ref:`t-name <qweb-directive-name>`), these changes will *not*
486 appear in the "child" templates.
488 .. _qweb-directive-jquery:
490 .. function:: t-jquery=selector [t-operation=operation] BODY
492 :param String selector: a CSS selector into the parent template
493 :param operation: one of ``append``, ``prepend``, ``before``,
494 ``after``, ``inner`` or ``replace``.
495 :param BODY: ``operation`` argument, or alterations to perform
497 * If ``operation`` is specified, applies the selector to the
498 parent template to find a *context node*, then applies
499 ``operation`` (as a jQuery operation) to the *context node*,
500 passing ``BODY`` as parameter.
504 ``replace`` maps to jQuery's `replaceWith(newContent)
505 <http://api.jquery.com/replaceWith/>`_, ``inner`` maps to
506 `html(htmlString) <http://api.jquery.com/html/>`_.
508 * If ``operation`` is not provided, ``BODY`` is evaluated as
509 javascript code, with the *context node* as ``this``.
513 While this second form is much more powerful than the first,
514 it is also much harder to read and maintain and should be
515 avoided. It is usually possible to either avoid it or
516 replace it with a sequence of ``t-jquery:t-operation:``.
518 Escape Hatches / debugging
519 ++++++++++++++++++++++++++
521 .. _qweb-directive-log:
523 .. function:: t-log=expression
525 :param Expression expression:
527 Evaluates the provided expression (in the current template
528 context) and logs its result via ``console.log``.
530 .. _qweb-directive-debug:
532 .. function:: t-debug
534 Injects a debugger breakpoint (via the ``debugger;`` statement) in
535 the compiled template output.
537 .. _qweb-directive-js:
539 .. function:: t-js=context BODY
542 :param BODY: javascript code
544 Injects the provided ``BODY`` javascript code into the compiled
545 template, passing it the current template context using the name
546 specified by ``context``.