[IMP] doc: try to clarify what $as is in qweb doc
[odoo/odoo.git] / doc / reference / qweb.rst
1 .. highlight:: xml
2
3 .. _reference/qweb:
4
5 ====
6 QWeb
7 ====
8
9 QWeb is the primary templating_ engine used by Odoo\ [#othertemplates]_. It
10 is an XML templating engine\ [#genshif]_ and used mostly to generate HTML_
11 fragments and pages.
12
13 Template directives are specified as XML attributes prefixed with ``t-``,
14 for instance ``t-if`` for :ref:`reference/qweb/conditionals`, with elements
15 and other attributes being rendered directly.
16
17 To avoid element rendering, a placeholder element ``<t>`` is also available,
18 which executes its directive but doesn't generate any output in and of
19 itself::
20
21     <t t-if="condition">
22         <p>Test</p>
23     </t>
24
25 will result in::
26
27     <p>Test</p>
28
29 if ``condition`` is true, but::
30
31     <div t-if="condition">
32         <p>Test</p>
33     </div>
34
35 will result in::
36
37     <div>
38         <p>Test</p>
39     </div>
40
41 .. _reference/qweb/output:
42
43 data output
44 ===========
45
46 QWeb has a primary output directive which automatically HTML-escape its
47 content limiting XSS_ risks when displaying user-provided content: ``esc``.
48
49 ``esc`` takes an expression, evaluates it and prints the content::
50
51     <p><t t-esc="value"/></p>
52
53 rendered with the value ``value`` set to ``42`` yields::
54
55     <p>42</p>
56
57 There is one other output directive ``raw`` which behaves the same as
58 respectively ``esc`` but *does not HTML-escape its output*. It can be useful
59 to display separately constructed markup (e.g. from functions) or already
60 sanitized user-provided markup.
61
62 .. _reference/qweb/conditionals:
63
64 conditionals
65 ============
66
67 QWeb has a conditional directive ``if``, which evaluates an expression given
68 as attribute value::
69
70     <div>
71         <t t-if="condition">
72             <p>ok</p>
73         </t>
74     </div>
75
76 The element is rendered if the condition is true::
77
78     <div>
79         <p>ok</p>
80     </div>
81
82 but if the condition is false it is removed from the result::
83
84     <div>
85     </div>
86
87 The conditional rendering applies to the bearer of the directive, which does
88 not have to be ``<t>``::
89
90     <div>
91         <p t-if="condition">ok</p>
92     </div>
93
94 will give the same results as the previous example.
95
96 .. _reference/qweb/loops:
97
98 loops
99 =====
100
101 QWeb has an iteration directive ``foreach`` which take an expression returning
102 the collection to iterate on, and a second parameter ``t-as`` providing the
103 name to use for the "current item" of the iteration::
104
105     <t t-foreach="[1, 2, 3]" t-as="i">
106         <p><t t-esc="i"/></p>
107     </t>
108
109 will be rendered as::
110
111     <p>1</p>
112     <p>2</p>
113     <p>3</p>
114
115 Like conditions, ``foreach`` applies to the element bearing the directive's
116 attribute, and
117
118 ::
119
120     <p t-foreach="[1, 2, 3]" t-as="i">
121         <t t-esc="i"/>
122     </p>
123
124 is equivalent to the previous example.
125
126 ``foreach`` can iterate on an array (the current item will be the current
127 value), a mapping (the current item will be the current key) or an integer
128 (equivalent to iterating on an array between 0 inclusive and the provided
129 integer exclusive).
130
131 In addition to the name passed via ``t-as``, ``foreach`` provides a few other
132 variables for various data points:
133
134 .. warning:: ``$as`` will be replaced by the name passed to ``t-as``
135
136 :samp:`{$as}_all`
137     the object being iterated over
138 :samp:`{$as}_value`
139     the current iteration value, identical to ``$as`` for lists and integers,
140     but for mappings it provides the value (where ``$as`` provides the key)
141 :samp:`{$as}_index`
142     the current iteration index (the first item of the iteration has index 0)
143 :samp:`{$as}_size`
144     the size of the collection if it is available
145 :samp:`{$as}_first`
146     whether the current item is the first of the iteration (equivalent to
147     :samp:`{$as}_index == 0`)
148 :samp:`{$as}_last`
149     whether the current item is the last of the iteration (equivalent to
150     :samp:`{$as}_index + 1 == {$as}_size`), requires the iteratee's size be
151     available
152 :samp:`{$as}_parity`
153     either ``"even"`` or ``"odd"``, the parity of the current iteration round
154 :samp:`{$as}_even`
155     a boolean flag indicating that the current iteration round is on an even
156     index
157 :samp:`{$as}_odd`
158     a boolean flag indicating that the current iteration round is on an odd
159     index
160
161 .. _reference/qweb/attributes:
162
163 attributes
164 ==========
165
166 QWeb can compute attributes on-the-fly and set the result of the computation
167 on the output node. This is done via the ``t-att`` (attribute) directive which
168 exists in 3 different forms:
169
170 :samp:`t-att-{$name}`
171     an attribute called ``$name`` is created, the attribute value is evaluated
172     and the result is set as the attribute's value::
173
174         <div t-att-a="42"/>
175
176     will be rendered as::
177
178         <div a="42"></div>
179 :samp:`t-attf-{$name}`
180     same as previous, but the parameter is a :term:`format string`
181     instead of just an expression, often useful to mix literal and non-literal
182     string (e.g. classes)::
183
184         <t t-foreach="[1, 2, 3]" t-as="item">
185             <li t-attf-class="row {{ item_parity }}"><t t-esc="item"/></li>
186         </t>
187
188     will be rendered as::
189
190         <li class="row even">1</li>
191         <li class="row odd">2</li>
192         <li class="row even">3</li>
193 :samp:`t-att=mapping`
194     if the parameter is a mapping, each (key, value) pair generates a new
195     attribute and its value::
196
197         <div t-att="{'a': 1, 'b': 2}"/>
198
199     will be rendered as::
200
201         <div a="1" b="2"></div>
202 :samp:`t-att=pair`
203     if the parameter is a pair (tuple or array of 2 element), the first
204     item of the pair is the name of the attribute and the second item is the
205     value::
206
207         <div t-att="['a', 'b']"/>
208
209     will be rendered as::
210
211         <div a="b"></div>
212
213 setting variables
214 =================
215
216 QWeb allows creating variables from within the template, to memoize a
217 computation (to use it multiple times), give a piece of data a clearer name,
218 ...
219
220 This is done via the ``set`` directive, which takes the name of the variable
221 to create. The value to set can be provided in two ways:
222
223 * a ``t-value`` attribute containing an expression, and the result of its
224   evaluation will be set::
225
226     <t t-set="foo" t-value="2 + 1"/>
227     <t t-esc="foo"/>
228
229   will print ``3``
230 * if there is no ``t-value`` attribute, the node's body is rendered and set
231   as the variable's value::
232
233     <t t-set="foo">
234         <li>ok</li>
235     </t>
236     <t t-esc="foo"/>
237
238   will generate ``&lt;li&gt;ok&lt;/li&gt;`` (the content is escaped as we
239   used the ``esc`` directive)
240
241   .. note:: using the result of this operation is a significant use-case for
242             the ``raw`` directive.
243
244 calling sub-templates
245 =====================
246
247 QWeb templates can be used for top-level rendering, but they can also be used
248 from within another template (to avoid duplication or give names to parts of
249 templates) using the ``t-call`` directive::
250
251     <t t-call="other-template"/>
252
253 This calls the named template with the execution context of the parent, if
254 ``other_template`` is defined as::
255
256     <p><t t-value="var"/></p>
257
258 the call above will be rendered as ``<p/>`` (no content), but::
259
260     <t t-set="var" t-value="1"/>
261     <t t-call="other-template"/>
262
263 will be rendered as ``<p>1</p>``.
264
265 However this has the problem of being visible from outside the ``t-call``.
266 Alternatively, content set in the body of the ``call`` directive will be
267 evaluated *before* calling the sub-template, and can alter a local context::
268
269     <t t-call="other-template">
270         <t t-set="var" t-value="1"/>
271     </t>
272     <!-- "var" does not exist here -->
273
274 The body of the ``call`` directive can be arbitrarily complex (not just
275 ``set`` directives), and its rendered form will be available within the called
276 template as a magical ``0`` variable::
277
278     <div>
279         This template was called with content:
280         <t t-raw="0"/>
281     </div>
282
283 being called thus::
284
285     <t t-call="other-template">
286         <em>content</em>
287     </t>
288
289 will result in::
290
291     <div>
292         This template was called with content:
293         <em>content</em>
294     </div>
295
296 Python
297 ======
298
299 Exclusive directives
300 --------------------
301
302 asset bundles
303 '''''''''''''
304
305 .. todo:: have fme write these up because I've no idea how they work
306
307 "smart records" fields formatting
308 '''''''''''''''''''''''''''''''''
309
310 The ``t-field`` directive can only be used when performing field access
311 (``a.b``) on a "smart" record (result of the ``browse`` method). It is able
312 to automatically format based on field type, and is integrated in the
313 website's rich text edition.
314
315 ``t-field-options`` can be used to customize fields, the most common option
316 is ``widget``, other options are field- or widget-dependent.
317
318 Helpers
319 -------
320
321 Request-based
322 '''''''''''''
323
324 Most Python-side uses of QWeb are in controllers (and during HTTP requests),
325 in which case templates stored in the database (as
326 :ref:`views <reference/views/qweb>`) can be trivially rendered by calling
327 :meth:`openerp.http.HttpRequest.render`:
328
329 .. code-block:: python
330
331     response = http.request.render('my-template', {
332         'context_value': 42
333     })
334
335 This automatically creates a :class:`~openerp.http.Response` object which can
336 be returned from the controller (or further customized to suit).
337
338 View-based
339 ''''''''''
340
341 At a deeper level than the previous helper is the ``render`` method on
342 ``ir.ui.view``:
343
344 .. py:method:: render(cr, uid, id[, values][, engine='ir.qweb][, context])
345
346     Renders a QWeb view/template by database id or :term:`external id`.
347     Templates are automatically loaded from ``ir.ui.view`` records.
348
349     Sets up a number of default values in the rendering context:
350
351     ``request``
352         the current :class:`~openerp.http.WebRequest` object, if any
353     ``debug``
354         whether the current request (if any) is in ``debug`` mode
355     :func:`quote_plus <werkzeug.urls.url_quote_plus>`
356         url-encoding utility function
357     :mod:`json`
358         the corresponding standard library module
359     :mod:`time`
360         the corresponding standard library module
361     :mod:`datetime`
362         the corresponding standard library module
363     `relativedelta <https://labix.org/python-dateutil#head-ba5ffd4df8111d1b83fc194b97ebecf837add454>`_
364         see module
365     ``keep_query``
366         the ``keep_query`` helper function
367
368     :param values: context values to pass to QWeb for rendering
369     :param str engine: name of the Odoo model to use for rendering, can be
370                        used to expand or customize QWeb locally (by creating
371                        a "new" qweb based on ``ir.qweb`` with alterations)
372
373 .. _reference/qweb/javascript:
374
375 API
376 ---
377
378 It is also possible to use the ``ir.qweb`` model directly (and extend it, and
379 inherit from it):
380
381 .. automodule:: openerp.addons.base.ir.ir_qweb
382     :members: QWeb, QWebContext, FieldConverter, QwebWidget
383
384 Javascript
385 ==========
386
387 Exclusive directives
388 --------------------
389
390 defining templates
391 ''''''''''''''''''
392
393 The ``t-name`` directive can only be placed at the top-level of a template
394 file (direct children to the document root)::
395
396     <templates>
397         <t t-name="template-name">
398             <!-- template code -->
399         </t>
400     </templates>
401
402 It takes no other parameter, but can be used with a ``<t>`` element or any
403 other. With a ``<t>`` element, the ``<t>`` should have a single child.
404
405 The template name is an arbitrary string, although when multiple templates
406 are related (e.g. called sub-templates) it is customary to use dot-separated
407 names to indicate hierarchical relationships.
408
409 template inheritance
410 ''''''''''''''''''''
411
412 Template inheritance is used to alter existing templates in-place, e.g. to
413 add information to templates created by an other modules.
414
415 Template inheritance is performed via the ``t-extend`` directive which takes
416 the name of the template to alter as parameter.
417
418 The alteration is then performed with any number of ``t-jquery``
419 sub-directives::
420
421     <t t-extends="base.template">
422         <t t-jquery="ul" t-operation="append">
423             <li>new element</li>
424         </t>
425     </t>
426
427 The ``t-jquery`` directives takes a `CSS selector`_. This selector is used
428 on the extended template to select *context nodes* to which the specified
429 ``t-operation`` is applied:
430
431 ``append``
432     the node's body is appended at the end of the context node (after the
433     context node's last child)
434 ``prepend``
435     the node's body is prepended to the context node (inserted before the
436     context node's first child)
437 ``before``
438     the node's body is inserted right before the context node
439 ``after``
440     the node's body is inserted right after the context node
441 ``inner``
442     the node's body replaces the context node's children
443 ``replace``
444     the node's body is used to replace the context node itself
445 No operation
446     if no ``t-operation`` is specified, the template body is interpreted as
447     javascript code and executed with the context node as ``this``
448
449     .. warning:: while much more powerful than other operations, this mode is
450                  also much harder to debug and maintain, it is recommended to
451                  avoid it
452
453 debugging
454 ---------
455
456 The javascript QWeb implementation provides a few debugging hooks:
457
458 ``t-log``
459     takes an expression parameter, evaluates the expression during rendering
460     and logs its result with ``console.log``
461 ``t-debug``
462     triggers a debugger breakpoint during template rendering
463 ``t-js``
464     the node's body is javascript code executed during template rendering.
465     Takes a ``context`` parameter, which is the name under which the rendering
466     context will be available in the ``t-js``'s body
467
468 Helpers
469 -------
470
471 .. js:attribute:: openerp.qweb
472
473     An instance of :js:class:`QWeb2.Engine` with all module-defined template
474     files loaded, and references to standard helper objects ``_``
475     (underscore), ``_t`` (translation function) and JSON_.
476
477     :js:func:`openerp.qweb.render <QWeb2.Engine.render>` can be used to
478     easily render basic module templates
479
480 API
481 ---
482
483 .. js:class:: QWeb2.Engine
484
485     The QWeb "renderer", handles most of QWeb's logic (loading,
486     parsing, compiling and rendering templates).
487
488     OpenERP Web instantiates one for the user, and sets it to
489     ``instance.web.qweb``. It also loads all the template files of the
490     various modules into that QWeb instance.
491
492     A :js:class:`QWeb2.Engine` also serves as a "template namespace".
493
494     .. js:function:: QWeb2.Engine.render(template[, context])
495
496         Renders a previously loaded template to a String, using
497         ``context`` (if provided) to find the variables accessed
498         during template rendering (e.g. strings to display).
499
500         :param String template: the name of the template to render
501         :param Object context: the basic namespace to use for template
502                                rendering
503         :returns: String
504
505     The engine exposes an other method which may be useful in some
506     cases (e.g. if you need a separate template namespace with, in
507     OpenERP Web, Kanban views get their own :js:class:`QWeb2.Engine`
508     instance so their templates don't collide with more general
509     "module" templates):
510
511     .. js:function:: QWeb2.Engine.add_template(templates)
512
513         Loads a template file (a collection of templates) in the QWeb
514         instance. The templates can be specified as:
515
516         An XML string
517             QWeb will attempt to parse it to an XML document then load
518             it.
519
520         A URL
521             QWeb will attempt to download the URL content, then load
522             the resulting XML string.
523
524         A ``Document`` or ``Node``
525             QWeb will traverse the first level of the document (the
526             child nodes of the provided root) and load any named
527             template or template override.
528
529         :type templates: String | Document | Node
530
531     A :js:class:`QWeb2.Engine` also exposes various attributes for
532     behavior customization:
533
534     .. js:attribute:: QWeb2.Engine.prefix
535
536         Prefix used to recognize directives during parsing. A string. By
537         default, ``t``.
538
539     .. js:attribute:: QWeb2.Engine.debug
540
541         Boolean flag putting the engine in "debug mode". Normally,
542         QWeb intercepts any error raised during template execution. In
543         debug mode, it leaves all exceptions go through without
544         intercepting them.
545
546     .. js:attribute:: QWeb2.Engine.jQuery
547
548         The jQuery instance used during template inheritance processing.
549         Defaults to ``window.jQuery``.
550
551     .. js:attribute:: QWeb2.Engine.preprocess_node
552
553         A ``Function``. If present, called before compiling each DOM
554         node to template code. In OpenERP Web, this is used to
555         automatically translate text content and some attributes in
556         templates. Defaults to ``null``.
557
558 .. [#genshif] it is similar in that to Genshi_, although it does not use (and
559               has no support for) `XML namespaces`_
560
561 .. [#othertemplates] although it uses a few others, either for historical
562                      reasons or because they remain better fits for the
563                      use case. Odoo 8.0 still depends on Jinja_ and Mako_.
564
565 .. _templating:
566     http://en.wikipedia.org/wiki/Template_processor
567
568 .. _Jinja: http://jinja.pocoo.org
569 .. _Mako: http://www.makotemplates.org
570 .. _Genshi: http://genshi.edgewall.org
571 .. _XML namespaces: http://en.wikipedia.org/wiki/XML_namespace
572 .. _HTML: http://en.wikipedia.org/wiki/HTML
573 .. _XSS: http://en.wikipedia.org/wiki/Cross-site_scripting
574 .. _JSON: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
575 .. _CSS selector: http://api.jquery.com/category/selectors/