[ADD] pyqweb-specific stuff, pyqweb APIDoc
authorXavier Morel <xmo@openerp.com>
Thu, 11 Sep 2014 13:52:38 +0000 (15:52 +0200)
committerXavier Morel <xmo@openerp.com>
Mon, 6 Oct 2014 17:13:46 +0000 (19:13 +0200)
doc/reference/qweb.rst
openerp/addons/base/ir/ir_qweb.py

index b57d78d..47a4d0a 100644 (file)
@@ -294,20 +294,97 @@ will result in::
 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:
 
+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
 ==========
 
 Exclusive directives
 --------------------
 
-The Javascript qweb implementation provides specific directives to handle
-defining and overloading/altering templates:
-
 defining templates
 ''''''''''''''''''
 
@@ -466,9 +543,8 @@ API
 
     .. js:attribute:: QWeb2.Engine.jQuery
 
-        The jQuery instance used during :ref:`template inheritance
-        <qweb-directives-inheritance>` processing. Defaults to
-        ``window.jQuery``.
+        The jQuery instance used during template inheritance processing.
+        Defaults to ``window.jQuery``.
 
     .. js:attribute:: QWeb2.Engine.preprocess_node
 
index 8504c15..9c90cf4 100644 (file)
@@ -80,6 +80,9 @@ class QWebContext(dict):
         return eval(expr, None, locals_dict, nocopy=True, locals_builtins=True)
 
     def copy(self):
+        """ Clones the current context, conserving all data and metadata
+        (loader, template cache, ...)
+        """
         return QWebContext(self.cr, self.uid, dict.copy(self),
                            loader=self.loader,
                            templates=self.templates,
@@ -89,28 +92,12 @@ class QWebContext(dict):
         return self.copy()
 
 class QWeb(orm.AbstractModel):
-    """QWeb Xml templating engine
-
-    The templating engine use a very simple syntax based "magic" xml
-    attributes, to produce textual output (even non-xml).
-
-    The core magic attributes are:
-
-    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.
+    """ Base QWeb rendering engine
 
-    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.
+    * to customize ``t-field`` rendering, subclass ``ir.qweb.field`` and
+      create new models called :samp:`ir.qweb.field.{widget}`
+    * alternatively, override :meth:`~.get_converter_for` and return an
+      arbitrary model to use as field converter
 
     Beware that if you need extensions or alterations which could be
     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):
         """
         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):
             # assume lxml.etree.Element
@@ -180,6 +170,12 @@ class QWeb(orm.AbstractModel):
                 res_id = None
 
     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]
         if qwebcontext.loader and name not in qwebcontext.templates:
             try:
@@ -232,6 +228,15 @@ class QWeb(orm.AbstractModel):
         return int(bool(self.eval(expr, qwebcontext)))
 
     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:
             qwebcontext = {}
 
@@ -475,9 +480,22 @@ class QWeb(orm.AbstractModel):
                                  element, template_attributes, generated_attributes, qwebcontext, context=qwebcontext.context)
 
     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'])
 
     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'
         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,
                    source_element, g_att, t_att, qweb_context,
                    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
         root node of the field conversion. Attribute values are escaped by the
         parent.
@@ -538,21 +557,26 @@ class FieldConverter(osv.AbstractModel):
         ]
 
     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 ''
         return value
 
     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
-        HTML
+        """ record_to_html(cr, uid, field_name, record, column, options=None, context=None)
+
+        Converts the specified field of the browse_record ``record`` to HTML
         """
         return self.value_to_html(
             cr, uid, record[field_name], column, options=options, context=context)
 
     def to_html(self, 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
+        """ 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
         of configuration values.
 
@@ -594,13 +618,16 @@ class FieldConverter(osv.AbstractModel):
 
     def render_element(self, cr, uid, source_element, t_att, g_att,
                        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(
             source_element, t_att, g_att, qweb_context, content or '')
 
     def user_lang(self, cr, uid, context):
-        """
+        """ user_lang(cr, uid, context)
+
         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
         context *or the language code is not valid*.