[IMP] qweb: document 't-cache' and 't-nocache' directives
related with: https://github.com/odoo/odoo/pull/88276 closes odoo/documentation#2056 Related: odoo/enterprise#27582 Related: odoo/upgrade#3451 Related: odoo/odoo#88276 Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
parent
f477cf5f1c
commit
7c4656f0c4
@ -491,6 +491,228 @@ Debugging
|
||||
|
||||
is equivalent to ``importlib.import_module("pdb").set_trace()``
|
||||
|
||||
Rendering cache:
|
||||
----------------
|
||||
|
||||
``t-cache="key_cache"`` tags part of template to be cached at rendering time.
|
||||
Every sub-directives will be call only during the first rendering. It means
|
||||
that the sql queries excecuted during the rendering of those sub-directives
|
||||
are also done only once.
|
||||
|
||||
``t-nocache="documentation"`` tags part of template to be render every time.
|
||||
The content can only use the root values.
|
||||
|
||||
Why and when to use ``t-cache``?
|
||||
''''''''''''''''''''''''''''''''
|
||||
|
||||
This directive is used to speed up the rendering, by caching parts of the final
|
||||
document, which may save queries to the database. However, it should be used
|
||||
sparingly, as ``t-cache`` will inevitably complicate templates (and their
|
||||
understanding of ``t-set`` for example).
|
||||
|
||||
However, in order to actually save database queries, it might be necessary to
|
||||
render the template with values that are evaluated lazily. If those lazy
|
||||
values are used in a cached part, they will not be evaluated if the part is
|
||||
available in cache.
|
||||
|
||||
The ``t-cache`` directive is useful for template parts using values that depend
|
||||
on a limited amount of data. We recommend to analyze the rendering of the
|
||||
template with the profiler (by activating the "**Add qweb directive context**"
|
||||
option). Passing lazy values to the rendering in controllers allow you to
|
||||
display the directives using these values and triggering the queries.
|
||||
|
||||
A concern of using such a cache are making it available to different users
|
||||
(different users should render the cached parts the same way). Another
|
||||
potential issue is to invalidate its entries when necessary. For the latter,
|
||||
the **key expression** should be chosen wisely. Using the ``write_date`` of a
|
||||
recordset can make a cache key out-of-date without having to discard it
|
||||
explicitly from the cache, for instance.
|
||||
|
||||
One should also pay attention to the fact that the values in ``t-cache`` parts
|
||||
are scoped. This implies that if there are ``t-set`` directives in this part of
|
||||
the template, the rendering of what comes after it could be different than if
|
||||
there was no ``t-cache`` directive.
|
||||
|
||||
What if there is a ``t-cache`` inside a ``t-cache``?
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The parts are cached. Each containing only the string corresponding to its
|
||||
rendering. Thus, the ``t-cache`` inside will probably be read less often, its
|
||||
cache key will not necessarily be used. If this must be the case, then you may
|
||||
need to add a ``t-nocache`` (on the same node or a parent).
|
||||
|
||||
What is ``t-nocache`` used for?
|
||||
'''''''''''''''''''''''''''''''
|
||||
|
||||
If you want to cache part of a template with ``t-cache`` but a small piece must
|
||||
remain dynamic and be evaluated at cache times. However, the part in
|
||||
``t-nocache`` will not have access to the ``t-set`` value of the template. Only
|
||||
the values provided by the controller are accessible there.
|
||||
For example, the menu is cached because it's the same all the time and takes
|
||||
time to render (using the performance devtools with the qweb context lets you
|
||||
investigate). However, in the menu, we want the ecommerce cart to be always up
|
||||
to date. So there is a ``t-nocache`` to keep this part dynamic.
|
||||
|
||||
The base of ``t-cache``
|
||||
'''''''''''''''''''''''
|
||||
|
||||
The ``t-cache`` directive allows you to store the rendered result of a template.
|
||||
The **key expression** (eg 42: ``t-cache="42"``) will be evaluated as a python
|
||||
expression. This will be used to generate the **cache key**. So there can be
|
||||
different **cache values** (cached render part) for the same template part. If
|
||||
the **key expression** is a tuple or a list, it will be searched when generating
|
||||
the **cache key**. If one or more recordsets are returned by the **key
|
||||
expression**, then the model, ids and their corresponding write_date will be
|
||||
used to generate the **cache key**. Special case: If the **key expression**
|
||||
returns a Falsy value, then the content will not be cached.
|
||||
|
||||
Example::
|
||||
|
||||
<div t-cache="record,bool(condition)">
|
||||
<span t-if="condition" t-field="record.partner_id.name">
|
||||
<span t-else="" t-field="record.partner_id" t-options-widget="contact">
|
||||
</div>
|
||||
|
||||
In this case, there may be values (string) in the cache corresponding to each
|
||||
record already returned with a true condition, as well as for the false
|
||||
condition. And if a module modifies the record, the write_date being modified,
|
||||
the cached value is discarded.
|
||||
|
||||
``t-cache`` and scoped values (``t-set``, ``t-foreach``...)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
Values in ``t-cache`` are scoped, this involves a change in behavior between
|
||||
having or not having ``t-cache`` on one of the parent nodes. Don't forget to
|
||||
take into account that Odoo uses a lot of templates, ``t-call`` and view
|
||||
inheritance. Adding a ``t-cache`` can therefore modify the rendering of a
|
||||
template that you do not see when editing.
|
||||
(``t-foreach`` it's like a ``t-set`` for each iteration)
|
||||
|
||||
Example::
|
||||
|
||||
<div>
|
||||
<t t-set="a" t-value="1"/>
|
||||
<inside>
|
||||
<t t-set="a" t-value="2"/>
|
||||
<t t-out="a"/>
|
||||
</inside>
|
||||
<outside t-out="a"/>
|
||||
|
||||
<t t-set="b" t-value="1"/>
|
||||
<inside t-cache="True">
|
||||
<t t-set="b" t-value="2"/>
|
||||
<t t-out="b"/>
|
||||
</inside>
|
||||
<outside t-out="b"/>
|
||||
</div>
|
||||
|
||||
Will render::
|
||||
|
||||
<div>
|
||||
<inside>2</inside>
|
||||
<outside>2</inside>
|
||||
|
||||
<inside>2</inside>
|
||||
<outside>1</inside>
|
||||
</div>
|
||||
|
||||
|
||||
The base of ``t-nocache``
|
||||
'''''''''''''''''''''''''
|
||||
|
||||
The template part contained in a node with a ``t-nocache`` attribute is not
|
||||
cached. This content is therefore **dynamic** and is rendered systematically.
|
||||
However the available values are those provided by the controller (when
|
||||
calling the ``_render`` method).
|
||||
|
||||
Example::
|
||||
|
||||
<section>
|
||||
<article t-cache="record">
|
||||
<title><t t-out="record.name"/> <i t-nocache="">(views: <t t-out="counter"/>)</i></titlle>
|
||||
<content t-out="record.description"/>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
Will render (counter = 1)::
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<title>The record name <i>(views: 1)</i></titlle>
|
||||
<content>Record description</content>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
Here the ``<i>`` tag that contains the container will always be rendered. While
|
||||
the rest is as a single string in the cache.
|
||||
|
||||
``t-nocache`` and scoped root values (``t-set``, ``t-foreach``...)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The contents of the ``t-nocache`` tag can be used for documentation and to
|
||||
explain why the directive is added.
|
||||
The values are scoped into ``t-nocache``, these values are root values only
|
||||
(values provided by the controller and/or when calling the ``_render`` method
|
||||
of ``ir.qweb``). ``t-set`` can be done in the template part, but will not be
|
||||
available elsewhere.
|
||||
|
||||
Example::
|
||||
|
||||
<section>
|
||||
<t t-set="counter" t-value="counter * 10"/>
|
||||
<header t-nocache="">
|
||||
<t t-set="counter" t-value="counter + 5"/>
|
||||
(views: <t t-out="counter"/>)
|
||||
</header>
|
||||
<article t-cache="record">
|
||||
<title><t t-out="record.name"/> <i t-nocache="">(views: <t t-out="counter"/>)</i></titlle>
|
||||
<content t-out="record.description"/>
|
||||
</article>
|
||||
<footer>(views: <t t-out="counter"/>)</footer>
|
||||
</section>
|
||||
|
||||
Will render (counter = 1)::
|
||||
|
||||
<section>
|
||||
<header>
|
||||
(views: 6)
|
||||
</header>
|
||||
<article>
|
||||
<title>The record name <i>(views: 1)</i></titlle>
|
||||
<content>Record description</content>
|
||||
</article>
|
||||
<footer>(views: 10)</footer>
|
||||
</section>
|
||||
|
||||
Here the ``<i>`` tag that contains the container will always be rendered. While
|
||||
the rest is as a single string in the cache. The counter is not updated by the
|
||||
``t-set`` out of the ``t-nocache``
|
||||
|
||||
``t-nocache-*`` add some primitive values in the cache
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
In order to be able to use values generated in the template, it is possible to
|
||||
cache them. The directive is used as ``t-nocache-*="expr"`` where ``*`` is the
|
||||
name of the chosen value and ``expr`` the python expression so the result will
|
||||
be cached. The cached value must be primitive type.
|
||||
|
||||
Example::
|
||||
|
||||
<section t-cache="records">
|
||||
<article t-foreach="records" t-as="record">
|
||||
<header>
|
||||
<title t-field="record.get_method_title()"/>
|
||||
</header>
|
||||
<footer t-nocache="This part has a dynamic counter and must be rendered all the time."
|
||||
t-nocache-cached_value="record.get_base_counter()">
|
||||
<span t-out="counter + cached_value"/>
|
||||
</footer>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
The value ``cached_value`` is cached with the cached template part of
|
||||
``t-cache="records"`` and add to the scoped root values each time.
|
||||
|
||||
Helpers
|
||||
-------
|
||||
|
||||
@ -514,15 +736,20 @@ be returned from the controller (or further customized to suit).
|
||||
View-based
|
||||
''''''''''
|
||||
|
||||
At a deeper level than the previous helper is the ``render`` method on
|
||||
``ir.ui.view``:
|
||||
At a deeper level than the previous helper is the ``_render`` method on
|
||||
``ir.qweb`` (use the datable) and the public module method ``render``
|
||||
(don't use the database):
|
||||
|
||||
.. py:method:: render(cr, uid, id[, values][, engine='ir.qweb][, context])
|
||||
.. py:method:: _render(id[, values])
|
||||
|
||||
Renders a QWeb view/template by database id or :term:`external id`.
|
||||
Templates are automatically loaded from ``ir.ui.view`` records.
|
||||
Templates are automatically loaded from ``ir.qweb`` records.
|
||||
|
||||
Sets up a number of default values in the rendering context:
|
||||
``_prepare_environment`` method sets up a number of default values in
|
||||
the rendering context. The ``http_routing`` and ``website`` addons,
|
||||
also default values they need.
|
||||
You can use ``minimal_qcontext=False`` option to avoid this default
|
||||
value like the public method ``render``:
|
||||
|
||||
``request``
|
||||
the current :class:`~odoo.http.Request` object, if any
|
||||
@ -546,6 +773,11 @@ At a deeper level than the previous helper is the ``render`` method on
|
||||
used to expand or customize QWeb locally (by creating
|
||||
a "new" qweb based on ``ir.qweb`` with alterations)
|
||||
|
||||
.. py:method:: render(template_name, values, load, **options)
|
||||
|
||||
:func:`load(ref)`
|
||||
returns etree object, ref
|
||||
|
||||
.. _reference/qweb/javascript:
|
||||
|
||||
.. todo:: the members below are no longer relevant, section to rewrite
|
||||
|
Loading…
Reference in New Issue
Block a user