[ADD] pyqweb-specific stuff, pyqweb APIDoc

This commit is contained in:
Xavier Morel 2014-09-11 15:52:38 +02:00
parent c5dca416da
commit 5954335222
2 changed files with 138 additions and 35 deletions

View File

@ -294,20 +294,97 @@ will result in::
Python Python
====== ======
Bundles Exclusive directives
--------------------
asset bundles
'''''''''''''
.. todo:: have fme write these up because I've no idea how they work
"smart records" fields formatting
'''''''''''''''''''''''''''''''''
The ``t-field`` directive can only be used when performing field access
(``a.b``) on a "smart" record (result of the ``browse`` method). It is able
to automatically format based on field type, and is integrated in the
website's rich text edition.
``t-field-options`` can be used to customize fields, the most common option
is ``widget``, other options are field- or widget-dependent.
Helpers
------- -------
Request-based
'''''''''''''
Most Python-side uses of QWeb are in controllers (and during HTTP requests),
in which case templates stored in the database (as
:ref:`views <reference/views/qweb>`) can be trivially rendered by calling
:meth:`openerp.http.HttpRequest.render`:
.. code-block:: python
response = http.request.render('my-template', {
'context_value': 42
})
This automatically creates a :class:`~openerp.http.Response` object which can
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``:
.. py:method:: render(cr, uid, id[, values][, engine='ir.qweb][, context])
Renders a QWeb view/template by database id or :term:`external id`.
Templates are automatically loaded from ``ir.ui.view`` records.
Sets up a number of default values in the rendering context:
``request``
the current :class:`~openerp.http.WebRequest` object, if any
``debug``
whether the current request (if any) is in ``debug`` mode
:func:`quote_plus <werkzeug.urls.url_quote_plus>`
url-encoding utility function
:mod:`json`
the corresponding standard library module
:mod:`time`
the corresponding standard library module
:mod:`datetime`
the corresponding standard library module
`relativedelta <https://labix.org/python-dateutil#head-ba5ffd4df8111d1b83fc194b97ebecf837add454>`_
see module
``keep_query``
the ``keep_query`` helper function
:param values: context values to pass to QWeb for rendering
:param str engine: name of the Odoo model to use for rendering, can be
used to expand or customize QWeb locally (by creating
a "new" qweb based on ``ir.qweb`` with alterations)
.. _reference/qweb/javascript: .. _reference/qweb/javascript:
API
---
It is also possible to use the ``ir.qweb`` model directly (and extend it, and
inherit from it):
.. automodule:: openerp.addons.base.ir.ir_qweb
:members: QWeb, QWebContext, FieldConverter, QwebWidget
Javascript Javascript
========== ==========
Exclusive directives Exclusive directives
-------------------- --------------------
The Javascript qweb implementation provides specific directives to handle
defining and overloading/altering templates:
defining templates defining templates
'''''''''''''''''' ''''''''''''''''''
@ -466,9 +543,8 @@ API
.. js:attribute:: QWeb2.Engine.jQuery .. js:attribute:: QWeb2.Engine.jQuery
The jQuery instance used during :ref:`template inheritance The jQuery instance used during template inheritance processing.
<qweb-directives-inheritance>` processing. Defaults to Defaults to ``window.jQuery``.
``window.jQuery``.
.. js:attribute:: QWeb2.Engine.preprocess_node .. js:attribute:: QWeb2.Engine.preprocess_node

View File

@ -80,6 +80,9 @@ class QWebContext(dict):
return eval(expr, None, locals_dict, nocopy=True, locals_builtins=True) return eval(expr, None, locals_dict, nocopy=True, locals_builtins=True)
def copy(self): def copy(self):
""" Clones the current context, conserving all data and metadata
(loader, template cache, ...)
"""
return QWebContext(self.cr, self.uid, dict.copy(self), return QWebContext(self.cr, self.uid, dict.copy(self),
loader=self.loader, loader=self.loader,
templates=self.templates, templates=self.templates,
@ -89,28 +92,12 @@ class QWebContext(dict):
return self.copy() return self.copy()
class QWeb(orm.AbstractModel): class QWeb(orm.AbstractModel):
"""QWeb Xml templating engine """ Base QWeb rendering engine
The templating engine use a very simple syntax based "magic" xml * to customize ``t-field`` rendering, subclass ``ir.qweb.field`` and
attributes, to produce textual output (even non-xml). create new models called :samp:`ir.qweb.field.{widget}`
* alternatively, override :meth:`~.get_converter_for` and return an
The core magic attributes are: arbitrary model to use as field converter
flow attributes:
t-if t-foreach t-call
output attributes:
t-att t-raw t-esc t-trim
assignation attribute:
t-set
QWeb can be extended like any OpenERP model and new attributes can be
added.
If you need to customize t-fields rendering, subclass the ir.qweb.field
model (and its sub-models) then override :meth:`~.get_converter_for` to
fetch the right field converters for your qweb model.
Beware that if you need extensions or alterations which could be Beware that if you need extensions or alterations which could be
incompatible with other subsystems, you should create a local object incompatible with other subsystems, you should create a local object
@ -162,6 +149,9 @@ class QWeb(orm.AbstractModel):
def load_document(self, document, res_id, qwebcontext): def load_document(self, document, res_id, qwebcontext):
""" """
Loads an XML document and installs any contained template in the engine Loads an XML document and installs any contained template in the engine
:type document: a parsed lxml.etree element, an unparsed XML document
(as a string) or the path of an XML file to load
""" """
if not isinstance(document, basestring): if not isinstance(document, basestring):
# assume lxml.etree.Element # assume lxml.etree.Element
@ -180,6 +170,12 @@ class QWeb(orm.AbstractModel):
res_id = None res_id = None
def get_template(self, name, qwebcontext): def get_template(self, name, qwebcontext):
""" Tries to fetch the template ``name``, either gets it from the
context's template cache or loads one with the context's loader (if
any).
:raises QWebTemplateNotFound: if the template can not be found or loaded
"""
origin_template = qwebcontext.get('__caller__') or qwebcontext['__stack__'][0] origin_template = qwebcontext.get('__caller__') or qwebcontext['__stack__'][0]
if qwebcontext.loader and name not in qwebcontext.templates: if qwebcontext.loader and name not in qwebcontext.templates:
try: try:
@ -232,6 +228,15 @@ class QWeb(orm.AbstractModel):
return int(bool(self.eval(expr, qwebcontext))) return int(bool(self.eval(expr, qwebcontext)))
def render(self, cr, uid, id_or_xml_id, qwebcontext=None, loader=None, context=None): def render(self, cr, uid, id_or_xml_id, qwebcontext=None, loader=None, context=None):
""" render(cr, uid, id_or_xml_id, qwebcontext=None, loader=None, context=None)
Renders the template specified by the provided template name
:param qwebcontext: context for rendering the template
:type qwebcontext: dict or :class:`QWebContext` instance
:param loader: if ``qwebcontext`` is a dict, loader set into the
context instantiated for rendering
"""
if qwebcontext is None: if qwebcontext is None:
qwebcontext = {} qwebcontext = {}
@ -475,9 +480,22 @@ class QWeb(orm.AbstractModel):
element, template_attributes, generated_attributes, qwebcontext, context=qwebcontext.context) element, template_attributes, generated_attributes, qwebcontext, context=qwebcontext.context)
def get_converter_for(self, field_type): def get_converter_for(self, field_type):
""" returns a :class:`~openerp.models.Model` used to render a
``t-field``.
By default, tries to get the model named
:samp:`ir.qweb.field.{field_type}`, falling back on ``ir.qweb.field``.
:param str field_type: type or widget of field to render
"""
return self.pool.get('ir.qweb.field.' + field_type, self.pool['ir.qweb.field']) return self.pool.get('ir.qweb.field.' + field_type, self.pool['ir.qweb.field'])
def get_widget_for(self, widget): def get_widget_for(self, widget):
""" returns a :class:`~openerp.models.Model` used to render a
``t-esc``
:param str widget: name of the widget to use, or ``None``
"""
widget_model = ('ir.qweb.widget.' + widget) if widget else 'ir.qweb.widget' widget_model = ('ir.qweb.widget.' + widget) if widget else 'ir.qweb.widget'
return self.pool.get(widget_model) or self.pool['ir.qweb.widget'] return self.pool.get(widget_model) or self.pool['ir.qweb.widget']
@ -509,7 +527,8 @@ class FieldConverter(osv.AbstractModel):
def attributes(self, cr, uid, field_name, record, options, def attributes(self, cr, uid, field_name, record, options,
source_element, g_att, t_att, qweb_context, source_element, g_att, t_att, qweb_context,
context=None): context=None):
""" """ attributes(cr, uid, field_name, record, options, source_element, g_att, t_att, qweb_context, context=None)
Generates the metadata attributes (prefixed by ``data-oe-`` for the Generates the metadata attributes (prefixed by ``data-oe-`` for the
root node of the field conversion. Attribute values are escaped by the root node of the field conversion. Attribute values are escaped by the
parent. parent.
@ -538,21 +557,26 @@ class FieldConverter(osv.AbstractModel):
] ]
def value_to_html(self, cr, uid, value, column, options=None, context=None): def value_to_html(self, cr, uid, value, column, options=None, context=None):
""" Converts a single value to its HTML version/output """ value_to_html(cr, uid, value, column, options=None, context=None)
Converts a single value to its HTML version/output
""" """
if not value: return '' if not value: return ''
return value return value
def record_to_html(self, cr, uid, field_name, record, column, options=None, context=None): def record_to_html(self, cr, uid, field_name, record, column, options=None, context=None):
""" Converts the specified field of the browse_record ``record`` to """ record_to_html(cr, uid, field_name, record, column, options=None, context=None)
HTML
Converts the specified field of the browse_record ``record`` to HTML
""" """
return self.value_to_html( return self.value_to_html(
cr, uid, record[field_name], column, options=options, context=context) cr, uid, record[field_name], column, options=options, context=context)
def to_html(self, cr, uid, field_name, record, options, def to_html(self, cr, uid, field_name, record, options,
source_element, t_att, g_att, qweb_context, context=None): source_element, t_att, g_att, qweb_context, context=None):
""" Converts a ``t-field`` to its HTML output. A ``t-field`` may be """ to_html(cr, uid, field_name, record, options, source_element, t_att, g_att, qweb_context, context=None)
Converts a ``t-field`` to its HTML output. A ``t-field`` may be
extended by a ``t-field-options``, which is a JSON-serialized mapping extended by a ``t-field-options``, which is a JSON-serialized mapping
of configuration values. of configuration values.
@ -594,13 +618,16 @@ class FieldConverter(osv.AbstractModel):
def render_element(self, cr, uid, source_element, t_att, g_att, def render_element(self, cr, uid, source_element, t_att, g_att,
qweb_context, content): qweb_context, content):
""" Final rendering hook, by default just calls ir.qweb's ``render_element`` """ render_element(cr, uid, source_element, t_att, g_att, qweb_context, content)
Final rendering hook, by default just calls ir.qweb's ``render_element``
""" """
return self.qweb_object().render_element( return self.qweb_object().render_element(
source_element, t_att, g_att, qweb_context, content or '') source_element, t_att, g_att, qweb_context, content or '')
def user_lang(self, cr, uid, context): def user_lang(self, cr, uid, context):
""" """ user_lang(cr, uid, context)
Fetches the res.lang object corresponding to the language code stored Fetches the res.lang object corresponding to the language code stored
in the user's context. Fallbacks to en_US if no lang is present in the in the user's context. Fallbacks to en_US if no lang is present in the
context *or the language code is not valid*. context *or the language code is not valid*.