From 9c339d8df3f84d2a5f4e9b2586d7cfb194d00b63 Mon Sep 17 00:00:00 2001
From: Xavier Morel <xmo@openerp.com>
Date: Mon, 1 Sep 2014 14:09:10 +0200
Subject: [PATCH] [ADD] web client tutorial/training

needs fixes, and corresponding web client reference
---
 doc/howtos/web.rst                  | 2348 +++++++++++++++++++++++++++
 doc/howtos/web/qweb.png             |  Bin 0 -> 40390 bytes
 doc/howtos/web/viewarchitecture.dia |  Bin 0 -> 1918 bytes
 doc/howtos/web/viewarchitecture.png |  Bin 0 -> 35268 bytes
 doc/howtos/web/viewarchitecture.svg |   89 +
 doc/tutorials.rst                   |    1 +
 6 files changed, 2438 insertions(+)
 create mode 100644 doc/howtos/web.rst
 create mode 100644 doc/howtos/web/qweb.png
 create mode 100644 doc/howtos/web/viewarchitecture.dia
 create mode 100644 doc/howtos/web/viewarchitecture.png
 create mode 100644 doc/howtos/web/viewarchitecture.svg

diff --git a/doc/howtos/web.rst b/doc/howtos/web.rst
new file mode 100644
index 000000000000..0460a791d1d6
--- /dev/null
+++ b/doc/howtos/web.rst
@@ -0,0 +1,2348 @@
+==========
+Web Client
+==========
+
+.. highlight:: javascript
+
+.. default-domain:: js
+
+This guide is about creating modules for Odoo's web client. To create websites
+with Odoo, see :doc:`website`.
+
+.. warning::
+
+    This guide assumes knowledge of:
+
+    * Javascript basics and good practices
+    * jQuery_
+    * `Underscore.js`_
+
+
+A Simple Module to Test the Web Framework
+-----------------------------------------
+
+It's not really possible to include the multiple JavaScript files that
+constitute the Odoo web framework in a simple HTML file like we did in the
+previous chapter. So we will create a simple module in Odoo that contains some
+configuration to have a web component that will give us the possibility to
+test the web framework.
+
+To download the example module, use this bazaar command:
+
+.. code-block:: sh
+
+    bzr branch lp:~niv-openerp/+junk/oepetstore -r 1
+
+Now you must add that folder to your the addons path when you launch Odoo
+(``--addons-path`` parameter when you launch the ``odoo.py`` executable). Then
+create a new database and install the new module ``oepetstore``.
+
+Now let's see what files exist in that module:
+
+.. code-block:: text
+
+    oepetstore
+    |-- __init__.py
+    |-- __openerp__.py
+    |-- petstore_data.xml
+    |-- petstore.py
+    |-- petstore.xml
+    `-- static
+        `-- src
+            |-- css
+            |   `-- petstore.css
+            |-- js
+            |   `-- petstore.js
+            `-- xml
+                `-- petstore.xml
+
+This new module already contains some customization that should be easy to
+understand if you already coded an Odoo module like a new table, some views,
+menu items, etc... We'll come back to these elements later because they will
+be useful to develop some example web module. Right now let's concentrate on
+the essential: the files dedicated to web development.
+
+Please note that all files to be used in the web part of an Odoo module must
+always be placed in a ``static`` folder inside the module. This is mandatory
+due to possible security issues. The fact we created the folders ``css``,
+``js`` and ``xml`` is just a convention.
+
+``oepetstore/static/css/petstore.css`` is our CSS file. It is empty right now
+but we will add any CSS we need later.
+
+``oepetstore/static/xml/petstore.xml`` is an XML file that will contain our
+QWeb templates. Right now it is almost empty too. Those templates will be
+explained later, in the part dedicated to QWeb templates.
+
+``oepetstore/static/js/petstore.js`` is probably the most interesting part. It
+contains the JavaScript of our application. Here is what it looks like right
+now::
+
+    openerp.oepetstore = function(instance) {
+        var _t = instance.web._t,
+            _lt = instance.web._lt;
+        var QWeb = instance.web.qweb;
+
+        instance.oepetstore = {};
+
+        instance.oepetstore.HomePage = instance.web.Widget.extend({
+            start: function() {
+                console.log("pet store home page loaded");
+            },
+        });
+
+        instance.web.client_actions.add('petstore.homepage', 'instance.oepetstore.HomePage');
+    }
+
+The multiple components of that file will explained progressively. Just know
+that it doesn't do much things right now except display a blank page and print
+a small message in the console.
+
+Like Odoo's XML files containing views or data, these files must be indicated
+in the ``__openerp__.py`` file. Here are the lines we added to explain to the
+web client it has to load these files:
+
+.. code-block:: python
+
+    'js': ['static/src/js/*.js'],
+    'css': ['static/src/css/*.css'],
+    'qweb': ['static/src/xml/*.xml'],
+
+These configuration parameters use wildcards, so we can add new files without
+altering ``__openerp__.py``: they will be loaded by the web client as long as
+they have the correct extension and are in the correct folder.
+
+.. warning::
+
+    In Odoo, all JavaScript files are, by default, concatenated in a single
+    file. Then we apply an operation called the *minification* on that
+    file. The minification will remove all comments, white spaces and
+    line-breaks in the file. Finally, it is sent to the user's browser.
+
+    That operation may seem complex, but it's a common procedure in big
+    application like Odoo with a lot of JavaScript files. It allows to load
+    the application a lot faster.
+
+    It has the main drawback to make the application almost impossible to
+    debug, which is very bad to develop. The solution to avoid this
+    side-effect and still be able to debug is to append a small argument to
+    the URL used to load Odoo: ``?debug``. So the URL will look like this:
+
+    .. code-block:: text
+
+        http://localhost:8069/?debug
+
+    When you use that type of URL, the application will not perform all that
+    concatenation-minification process on the JavaScript files. The
+    application will take more time to load but you will be able to develop
+    with decent debugging tools.
+
+Odoo JavaScript Module
+-------------------------
+
+In the previous chapter, we explained that JavaScript do not have a correct
+mechanism to namespace the variables declared in different JavaScript files
+and we proposed a simple method called the Module pattern.
+
+In Odoo's web framework there is an equivalent of that pattern which is
+integrated with the rest of the framework.  Please note that **an Odoo web
+module is a separate concept from an Odoo addon**. An addon is a folder with a
+lot of files, a web module is not much more than a namespace for JavaScript.
+
+The ``oepetstore/static/js/petstore.js`` already declare such a module::
+
+    openerp.oepetstore = function(instance) {
+        instance.oepetstore = {};
+
+        instance.oepetstore.xxx = ...;
+    }
+
+In Odoo's web framework, you declare a JavaScript module by declaring a
+function that you put in the global variable ``openerp``. The attribute you
+set in that object must have the exact same name than your Odoo addon (this
+addon is named ``oepetstore``, if I set ``openerp.petstore`` instead of
+``openerp.oepetstore`` that will not work).
+
+That function will be called when the web client decides to load your
+addon. It is given a parameter named ``instance``, which represents the
+current Odoo web client instance and contains all the data related to the
+current session as well as the variables of all web modules.
+
+The convention is to create a new namespace inside the ``instance`` object
+which has the same name than you addon.  That's why we set an empty dictionary
+in ``instance.oepetstore``. That dictionary is the namespace we will use to
+declare all classes and variables used inside our module.
+
+Classes
+-------
+
+JavaScript doesn't have a class mechanism like most object-oriented
+programming languages. To be more exact, it provides language elements to make
+object-oriented programming but you have to define by yourself how you choose
+to do it.  Odoo's web framework provide tools to simplify this and let
+programmers code in a similar way they would program in other languages like
+Java. That class system is heavily inspired by John Resig's `Simple JavaScript
+Inheritance <http://ejohn.org/blog/simple-javascript-inheritance/>`_.
+
+To define a new class, you need to extend the :class:`openerp.web.Class`
+class::
+
+    instance.oepetstore.MyClass = instance.web.Class.extend({
+        say_hello: function() {
+            console.log("hello");
+        },
+    });
+
+As you can see, you have to call :func:`instance.web.Class.extend` and give
+it a dictionary. That dictionary will contain the methods and class attributes
+of our new class. Here we simply put a method named ``say_hello()``. This
+class can be instantiated and used like this::
+
+    var my_object = new instance.oepetstore.MyClass();
+    my_object.say_hello();
+    // print "hello" in the console
+
+You can access the attributes of a class inside a method using ``this``::
+
+    instance.oepetstore.MyClass = instance.web.Class.extend({
+        say_hello: function() {
+            console.log("hello", this.name);
+        },
+    });
+
+    var my_object = new instance.oepetstore.MyClass();
+    my_object.name = "Nicolas";
+    my_object.say_hello();
+    // print "hello Nicolas" in the console
+
+Classes can have a constructor, it is just a method named ``init()``. You can
+pass parameters to the constructor like in most language::
+
+    instance.oepetstore.MyClass = instance.web.Class.extend({
+        init: function(name) {
+            this.name = name;
+        },
+        say_hello: function() {
+            console.log("hello", this.name);
+        },
+    });
+
+    var my_object = new instance.oepetstore.MyClass("Nicolas");
+    my_object.say_hello();
+    // print "hello Nicolas" in the console
+
+Classes can be inherited. To do so, use :func:`~openerp.web.Class.extend`
+directly on your class just like you extended :class:`~openerp.web.Class`::
+
+    instance.oepetstore.MySpanishClass = instance.oepetstore.MyClass.extend({
+        say_hello: function() {
+            console.log("hola", this.name);
+        },
+    });
+
+    var my_object = new instance.oepetstore.MySpanishClass("Nicolas");
+    my_object.say_hello();
+    // print "hola Nicolas" in the console
+
+When overriding a method using inheritance, you can use ``this._super()`` to
+call the original method. ``this._super()`` is not a normal method of your
+class, you can consider it's magic. Example::
+
+    instance.oepetstore.MySpanishClass = instance.oepetstore.MyClass.extend({
+        say_hello: function() {
+            this._super();
+            console.log("translation in Spanish: hola", this.name);
+        },
+    });
+
+    var my_object = new instance.oepetstore.MySpanishClass("Nicolas");
+    my_object.say_hello();
+    // print "hello Nicolas \n translation in Spanish: hola Nicolas" in the console
+
+Widgets Basics
+--------------
+
+In previous chapter we discovered jQuery and its DOM manipulation tools. It's
+useful, but it's not sufficient to structure a real application. Graphical
+user interface libraries like Qt, GTK or Windows Forms have classes to
+represent visual components. In Odoo, we have the
+:class:`~openerp.web.Widget` class. A widget is a generic component
+dedicated to display content to the user.
+
+Your First Widget
+%%%%%%%%%%%%%%%%%
+
+The start module you installed already contains a small widget::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            console.log("pet store home page loaded");
+        },
+    });
+
+Here we create a simple widget by extending the :class:`openerp.web.Widget`
+class. This one defines a method named :func:`~openerp.web.Widget.start` that
+doesn't do anything really interesting right now.
+
+You may also have noticed this line at the end of the file::
+
+    instance.web.client_actions.add('petstore.homepage', 'instance.oepetstore.HomePage');
+
+This last line registers our basic widget as a client action. Client actions
+will be explained in the next part of this guide. For now, just remember that
+this is what allows our widget to be displayed when we click on the
+:menuselection:`Pet Store --> Pet Store --> Home Page` menu element.
+
+Display Content
+%%%%%%%%%%%%%%%
+
+Widgets have a lot of methods and features, but let's start with the basics:
+display some data inside the widget and how to instantiate a widget and
+display it.
+
+The ``HomePage`` widget already has a :func:`~openerp.web.Widget.start`
+method. That method is automatically called after the widget has been
+instantiated and it has received the order to display its content. We will use
+it to display some content to the user.
+
+To do so, we will also use the :attr:`~openerp.web.Widget.$el` attribute
+that all widgets contain. That attribute is a jQuery object with a reference
+to the HTML element that represents the root of our widget. A widget can
+contain multiple HTML elements, but they must be contained inside one single
+element. By default, all widgets have an empty root element which is a
+``<div>`` HTML element.
+
+A ``<div>`` element in HTML is usually invisible for the user if it does not
+have any content. That explains why when the ``instance.oepetstore.HomePage``
+widget is displayed you can't see anything: it simply doesn't have any
+content. To show something, we will use some simple jQuery methods on that
+object to add some HTML in our root element::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            this.$el.append("<div>Hello dear Odoo user!</div>");
+        },
+    });
+
+That message will now appear when you go to the menu :menuselection:`Pet Store
+--> Pet Store --> Home Page` (remember you need to refresh your web browser,
+although there is not need to restart Odoo's server).
+
+Now you should learn how to instantiate a widget and display its content. To
+do so, we will create a new widget::
+
+    instance.oepetstore.GreetingsWidget = instance.web.Widget.extend({
+        start: function() {
+            this.$el.append("<div>We are so happy to see you again in this menu!</div>");
+        },
+    });
+
+Now we want to display the ``instance.oepetstore.GreetingsWidget`` inside the
+home page. To do so we can use the :func:`~openerp.web.Widget.append`
+method of ``Widget``::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            this.$el.append("<div>Hello dear Odoo user!</div>");
+            var greeting = new instance.oepetstore.GreetingsWidget(this);
+            greeting.appendTo(this.$el);
+        },
+    });
+
+Here, the ``HomePage`` instantiate a ``GreetingsWidget`` (the first argument
+of the constructor of ``GreetingsWidget`` will be explained in the next
+part). Then it asks the ``GreetingsWidget`` to insert itself inside the DOM,
+more precisely directly under the ``HomePage`` widget.
+
+When the :func:`~openerp.web.Widget.appendTo` method is called, it asks the
+widget to insert itself and to display its content. It's during the call to
+:func:`~openerp.web.Widget.appentTo` that the
+:func:`~openerp.web.Widget.start` method will be called.
+
+To check the consequences of that code, let's use Chrome's DOM explorer. But
+before that we will modify a little bit our widgets to have some classes on
+some of our ``<div>`` elements so we can clearly see them in the explorer::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            this.$el.addClass("oe_petstore_homepage");
+            ...
+        },
+    });
+    instance.oepetstore.GreetingsWidget = instance.web.Widget.extend({
+        start: function() {
+            this.$el.addClass("oe_petstore_greetings");
+            ...
+        },
+    });
+
+The result will be this if you can find the correct DOM part in the DOM explorer:
+
+.. code-block:: html
+
+    <div class="oe_petstore_homepage">
+        <div>Hello dear Odoo user!</div>
+        <div class="oe_petstore_greetings">
+            <div>We are so happy to see you again in this menu!</div>
+        </div>
+    </div>
+
+Here we can clearly see the two ``<div>`` created implicitly by
+:class:`~openerp.web.Widget`, because we added some classes on them. We can
+also see the two divs containing messages we created using the jQuery methods
+on ``$el``. Finally, note the ``<div class="oe_petstore_greetings">`` element
+which represents the ``GreetingsWidget`` instance is *inside* the ``<div
+class="oe_petstore_homepage">`` which represents the ``HomePage`` instance.
+
+Widget Parents and Children
+%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+In the previous part, we instantiated a widget using this syntax::
+
+    new instance.oepetstore.GreetingsWidget(this);
+
+The first argument is ``this``, which in that case was a ``HomePage``
+instance. This serves to indicate the Widget what other widget is his parent.
+
+As we've seen, widgets are usually inserted in the DOM by another widget and
+*inside* that other widget. This means most widgets are always a part of
+another widget. We call the container the *parent*, and the contained widget
+the *child*.
+
+Due to multiple technical and conceptual reasons, it is necessary for a widget
+to know who is his parent and who are its children. This is why we have that
+first parameter in the constructor of all widgets.
+
+:func:`~openerp.web.Widget.getParent` can be used to get the parent of a
+widget::
+
+    instance.oepetstore.GreetingsWidget = instance.web.Widget.extend({
+        start: function() {
+            console.log(this.getParent().$el );
+            // will print "div.oe_petstore_homepage" in the console
+        },
+    });
+
+:func:`~openerp.web.Widget.getChildren` can be used to get a list of its
+children::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            var greeting = new instance.oepetstore.GreetingsWidget(this);
+            greeting.appendTo(this.$el);
+            console.log(this.getChildren()[0].$el);
+            // will print "div.oe_petstore_greetings" in the console
+        },
+    });
+
+You should also remember that, when you override the
+:func:`~openerp.web.Widget.init` method of a widget you should always put the
+parent as first parameter are pass it to ``this._super()``::
+
+    instance.oepetstore.GreetingsWidget = instance.web.Widget.extend({
+        init: function(parent, name) {
+            this._super(parent);
+            this.name = name;
+        },
+    });
+
+Finally, if a widget does not logically have a parent (ie: because it's the
+first widget you instantiate in an application), you can give null as a parent
+instead::
+
+    new instance.oepetstore.GreetingsWidget(null);
+
+Destroying Widgets
+%%%%%%%%%%%%%%%%%%
+
+If you can display content to your users, you should also be able to erase
+it. This can simply be done using the :func:`~openerp.web.Widget.destroy`
+method:
+
+    greeting.destroy();
+
+When a widget is destroyed it will first call
+:func:`~openerp.web.Widget.destroy` on all its children. Then it erases itself
+from the DOM. The recursive call to destroy from parents to children is very
+useful to clean properly complex structures of widgets and avoid memory leaks
+that can easily appear in big JavaScript applications.
+
+.. _howtos/web/qweb:
+
+The QWeb Template Engine
+------------------------
+
+The previous part of the guide showed how to define widgets that are able to
+display HTML to the user. The example ``GreetingsWidget`` used a syntax like
+this::
+
+    this.$el.append("<div>Hello dear Odoo user!</div>");
+
+This technically allow us to display any HTML, even if it is very complex and
+require to be generated by code. Although generating text using pure
+JavaScript is not very nice, that would necessitate to copy-paste a lot of
+HTML lines inside our JavaScript source file, add the ``"`` character at the
+beginning and the end of each line, etc...
+
+The problem is exactly the same in most programming languages needing to
+generate HTML. That's why they typically use template engines. Example of
+template engines are Velocity, JSP (Java), Mako, Jinja (Python), Smarty (PHP),
+etc...
+
+In Odoo we use a template engine developed specifically for Odoo's web
+client. Its name is QWeb.
+
+QWeb is an XML-based templating language, similar to `Genshi
+<http://en.wikipedia.org/wiki/Genshi_(templating_language)>`_, `Thymeleaf
+<http://en.wikipedia.org/wiki/Thymeleaf>`_ or `Facelets
+<http://en.wikipedia.org/wiki/Facelets>`_ with a few peculiarities:
+
+* It's implemented fully in JavaScript and rendered in the browser.
+* Each template file (XML files) contains multiple templates, where template
+  engine usually have a 1:1 mapping between template files and templates.
+* It has special support in Odoo Web's :class:`~openerp.web.Widget`, though it
+  can be used outside of Odoo's web client (and it's possible to use
+  :class:`~openerp.web.Widget` without relying on QWeb).
+
+The rationale behind using QWeb instead of existing javascript template
+engines is that its extension mechanism is very similar to the Odoo view
+inheritance mechanism. Like Odoo views a QWeb template is an XML tree and
+therefore XPath or DOM manipulations are easy to perform on it.
+
+Using QWeb inside a Widget
+%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+First let's define a simple QWeb template in
+``oepetstore/static/src/xml/petstore.xml`` file, the exact meaning will be
+explained later:
+
+.. code-block:: xml
+
+    <?xml version="1.0" encoding="UTF-8"?>
+
+    <templates xml:space="preserve">
+        <t t-name="HomePageTemplate">
+            <div style="background-color: red;">This is some simple HTML</div>
+        </t>
+    </templates>
+
+Now let's modify the ``HomePage`` class. Remember that enigmatic line at the
+beginning the the JavaScript source file?
+
+::
+
+    var QWeb = instance.web.qweb;
+
+This is a line we recommend to copy-paste in all Odoo web modules. It is the
+object giving access to all templates defined in template files that were
+loaded by the web client. We can use the template we defined in our XML
+template file like this::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            this.$el.append(QWeb.render("HomePageTemplate"));
+        },
+    });
+
+Calling the ``QWeb.render()`` method asks to render the template identified by
+the string passed as first parameter.
+
+Another possibility commonly seen in Odoo code is to use ``Widget``'s
+integration with QWeb::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        template: "HomePageTemplate",
+        start: function() {
+            ...
+        },
+    });
+
+When you put a ``template`` class attribute in a widget, the widget knows it
+has to call ``QWeb.render()`` to render that template.
+
+Please note there is a difference between those two syntaxes. When you use
+``Widget``'s QWeb integration the ``QWeb.render()`` method is called *before*
+the widget calls :func:`~openerp.web.Widget.start`. It will also take the root
+element of the rendered template and put it as a replacement of the default
+root element generated by the :class:`~openerp.web.Widget` class. This will
+alter the behavior, so you should remember it.
+
+QWeb Context
+''''''''''''
+
+Like with all template engines, QWeb templates can contain code able to
+manipulate data that is given to the template.  To pass data to QWeb, use the
+second argument to ``QWeb.render()``:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div>Hello <t t-esc="name"/></div>
+    </t>
+
+::
+
+    QWeb.render("HomePageTemplate", {name: "Nicolas"});
+
+Result:
+
+.. code-block:: html
+
+    <div>Hello Nicolas</div>
+
+When you use :class:`~openerp.web.Widget`'s integration you can not pass
+additional data to the template. Instead the template will have a unique
+``widget`` variable which is a reference to the current widget:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div>Hello <t t-esc="widget.name"/></div>
+    </t>
+
+::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        template: "HomePageTemplate",
+        init: function(parent) {
+            this._super(parent);
+            this.name = "Nicolas";
+        },
+        start: function() {
+        },
+    });
+
+Result:
+
+.. code-block:: html
+
+    <div>Hello Nicolas</div>
+
+Template Declaration
+''''''''''''''''''''
+
+Now that we know everything about rendering templates we can try to understand
+QWeb's syntax.
+
+All QWeb directives use XML attributes beginning with the prefix ``t-``. To
+declare new templates, we add a ``<t t-name="...">`` element into the XML
+template file inside the root element ``<templates>``::
+
+    <templates>
+        <t t-name="HomePageTemplate">
+            <div>This is some simple HTML</div>
+        </t>
+    </templates>
+
+``t-name`` simply declares a template that can be called using
+``QWeb.render()``.
+
+Escaping
+''''''''
+
+To put some text in the HTML, use ``t-esc``:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div>Hello <t t-esc="name"/></div>
+    </t>
+
+
+This will output the variable ``name`` and escape its content in case it
+contains some characters that looks like HTML.  Please note the attribute
+``t-esc`` can contain any type of JavaScript expression:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div><t t-esc="3+5"/></div>
+    </t>
+
+Will render:
+
+.. code-block:: html
+
+    <div>8</div>
+
+Outputting HTML
+'''''''''''''''
+
+If you know you have some HTML contained in a variable, use ``t-raw`` instead
+of ``t-esc``:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div><t t-raw="some_html"/></div>
+    </t>
+
+If
+''
+
+The basic alternative block of QWeb is ``t-if``:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div>
+            <t t-if="true == true">
+                true is true
+            </t>
+            <t t-if="true == false">
+                true is not true
+            </t>
+        </div>
+    </t>
+
+Although QWeb does not contains any structure for else.
+
+Foreach
+'''''''
+
+To iterate on a list, use ``t-foreach`` and ``t-as``:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div>
+            <t t-foreach="names" t-as="name">
+                <div>
+                    Hello <t t-esc="name"/>
+                </div>
+            </t>
+        </div>
+    </t>
+
+Setting the Value of an XML Attribute
+'''''''''''''''''''''''''''''''''''''
+
+QWeb has a special syntax to set the value of an attribute. You must use
+``t-att-xxx`` and replace ``xxx`` with the name of the attribute:
+
+.. code-block:: xml
+
+    <t t-name="HomePageTemplate">
+        <div>
+            Input your name:
+            <input type="text" t-att-value="defaultName"/>
+        </div>
+    </t>
+
+To Learn More About QWeb
+''''''''''''''''''''''''
+
+For a QWeb reference, see :ref:`reference/qweb`.
+
+Exercise
+''''''''
+
+.. exercise:: Usage of QWeb in Widgets
+
+    Create a widget whose constructor contains two parameters aside from
+    ``parent``: ``product_names`` and ``color``.  ``product_names`` is a list
+    of strings, each one being a name of product. ``color`` is a string
+    containing a color in CSS color format (ie: ``#000000`` for black). That
+    widget should display the given product names one under the other, each
+    one in a separate box with a background color with the value of ``color``
+    and a border. You must use QWeb to render the HTML. This exercise will
+    necessitate some CSS that you should put in
+    ``oepetstore/static/src/css/petstore.css``. Display that widget in the
+    ``HomePage`` widget with a list of five products and green as the
+    background color for boxes.
+
+    .. only:: solutions
+
+        ::
+
+            openerp.oepetstore = function(instance) {
+                var _t = instance.web._t,
+                    _lt = instance.web._lt;
+                var QWeb = instance.web.qweb;
+
+                instance.oepetstore = {};
+
+                instance.oepetstore.HomePage = instance.web.Widget.extend({
+                    start: function() {
+                        var products = new instance.oepetstore.ProductsWidget(this, ["cpu", "mouse", "keyboard", "graphic card", "screen"], "#00FF00");
+                        products.appendTo(this.$el);
+                    },
+                });
+
+                instance.oepetstore.ProductsWidget = instance.web.Widget.extend({
+                    template: "ProductsWidget",
+                    init: function(parent, products, color) {
+                        this._super(parent);
+                        this.products = products;
+                        this.color = color;
+                    },
+                });
+
+                instance.web.client_actions.add('petstore.homepage', 'instance.oepetstore.HomePage');
+            }
+
+        .. code-block:: xml
+
+            <?xml version="1.0" encoding="UTF-8"?>
+
+            <templates xml:space="preserve">
+                <t t-name="ProductsWidget">
+                    <div>
+                        <t t-foreach="widget.products" t-as="product">
+                            <span class="oe_products_item" t-att-style="'background-color: ' + widget.color + ';'"><t t-esc="product"/></span><br/>
+                        </t>
+                    </div>
+                </t>
+            </templates>
+
+        .. code-block:: css
+
+            .oe_products_item {
+                display: inline-block;
+                padding: 3px;
+                margin: 5px;
+                border: 1px solid black;
+                border-radius: 3px;
+            }
+
+        .. image:: web/qweb.*
+           :align: center
+           :width: 70%
+
+Widget Events and Properties
+----------------------------
+
+Widgets still have more helper to learn. One of the more complex (and useful)
+one is the event system. Events are also closely related to the widget
+properties.
+
+Events
+%%%%%%
+
+Widgets are able to fire events in a similar way most components in existing
+graphical user interfaces libraries (Qt, GTK, Swing,...) handle
+them. Example::
+
+    instance.oepetstore.ConfirmWidget = instance.web.Widget.extend({
+        start: function() {
+            var self = this;
+            this.$el.append("<div>Are you sure you want to perform this action?</div>" +
+                "<button class='ok_button'>Ok</button>" +
+                "<button class='cancel_button'>Cancel</button>");
+            this.$el.find("button.ok_button").click(function() {
+                self.trigger("user_choose", true);
+            });
+            this.$el.find("button.cancel_button").click(function() {
+                self.trigger("user_choose", false);
+            });
+        },
+    });
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            var widget = new instance.oepetstore.ConfirmWidget(this);
+            widget.on("user_choose", this, this.user_choose);
+            widget.appendTo(this.$el);
+        },
+        user_choose: function(confirm) {
+            if (confirm) {
+                console.log("The user agreed to continue");
+            } else {
+                console.log("The user refused to continue");
+            }
+        },
+    });
+
+First, we will explain what this example is supposed to do. We create a
+generic widget to ask the user if he really wants to do an action that could
+have important consequences (a type widget heavily used in Windows). To do so,
+we put two buttons in the widget. Then we bind jQuery events to know when the
+user click these buttons.
+
+.. note::
+
+    It could be hard to understand this particular line::
+
+        var self = this;
+
+    Remember, in JavaScript the variable ``this`` is a variable that is passed
+    implicitly to all functions. It allows us to know which is the object if
+    function is used like a method. Each declared function has its own
+    ``this``. So, when we declare a function inside a function, that new
+    function will have its own ``this`` that could be different from the
+    ``this`` of the parent function. If we want to remember the original
+    object the simplest method is to store a reference in a variable. By
+    convention in Odoo we very often name that variable ``self`` because it's
+    the equivalent of ``this`` in Python.
+
+Since our widget is supposed to be generic, it should not perform any precise
+action by itself. So, we simply make it trigger and event named
+``user_choose`` by using the :func:`~openerp.web.Widget.trigger` method.
+
+:func:`~openerp.web.Widget.trigger` takes as first argument the name of the
+event to trigger. Then it can takes any number of additional arguments. These
+arguments will be passed to all the event listeners.
+
+Then we modify the ``HomePage`` widget to instantiate a ``ConfirmWidget`` and
+listen to its ``user_choose`` event by calling the
+:func:`~openerp.web.Widget.on` method.
+
+:func:`~openerp.web.Widget.on` allows to bind a function to be called when the
+event identified by event_name is ``triggered``. The ``func`` argument is the
+function to call and ``object`` is the object to which that function is
+related if it is a method. The binded function will be called with the
+additional arguments of :func:`~openerp.web.Widget.trigger` if it has
+any. Example::
+
+    start: function() {
+        var widget = ...
+        widget.on("my_event", this, this.my_event_triggered);
+        widget.trigger("my_event", 1, 2, 3);
+    },
+    my_event_triggered: function(a, b, c) {
+        console.log(a, b, c);
+        // will print "1 2 3"
+    }
+
+Properties
+%%%%%%%%%%
+
+Properties are very similar to normal object attributes. They allow to set
+data on an object but with an additional feature: it triggers events when a
+property's value has changed::
+
+    start: function() {
+        this.widget = ...
+        this.widget.on("change:name", this, this.name_changed);
+        this.widget.set("name", "Nicolas");
+    },
+    name_changed: function() {
+        console.log("The new value of the property 'name' is", this.widget.get("name"));
+    }
+
+:func:`~openerp.web.Widget.set` allows to set the value of property. If the
+value changed (or it didn't had a value previously) the object will trigger a
+``change:xxx`` where ``xxx`` is the name of the property.
+
+:func:`~openerp.web.Widget.get` allows to retrieve the value of a property.
+
+Exercise
+%%%%%%%%
+
+.. exercise:: Widget Properties and Events
+
+    Create a widget ``ColorInputWidget`` that will display 3 ``<input
+    type="text">``. Each of these ``<input>`` is dedicated to type a
+    hexadecimal number from 00 to FF. When any of these ``<input>`` is
+    modified by the user the widget must query the content of the three
+    ``<input>``, concatenate their values to have a complete CSS color code
+    (ie: ``#00FF00``) and put the result in a property named ``color``. Please
+    note the jQuery ``change()`` event that you can bind on any HTML
+    ``<input>`` element and the ``val()`` method that can query the current
+    value of that ``<input>`` could be useful to you for this exercise.
+
+    Then, modify the ``HomePage`` widget to instantiate ``ColorInputWidget``
+    and display it. The ``HomePage`` widget should also display an empty
+    rectangle. That rectangle must always, at any moment, have the same
+    background color than the color in the ``color`` property of the
+    ``ColorInputWidget`` instance.
+
+    Use QWeb to generate all HTML.
+
+    .. only:: solutions
+
+        ::
+
+            openerp.oepetstore = function(instance) {
+                var _t = instance.web._t,
+                    _lt = instance.web._lt;
+                var QWeb = instance.web.qweb;
+
+                instance.oepetstore = {};
+
+                instance.oepetstore.ColorInputWidget = instance.web.Widget.extend({
+                    template: "ColorInputWidget",
+                    start: function() {
+                        var self = this;
+                        this.$el.find("input").change(function() {
+                            self.input_changed();
+                        });
+                        self.input_changed();
+                    },
+                    input_changed: function() {
+                        var color = "#";
+                        color += this.$el.find(".oe_color_red").val();
+                        color += this.$el.find(".oe_color_green").val();
+                        color += this.$el.find(".oe_color_blue").val();
+                        this.set("color", color);
+                    },
+                });
+
+                instance.oepetstore.HomePage = instance.web.Widget.extend({
+                    template: "HomePage",
+                    start: function() {
+                        this.colorInput = new instance.oepetstore.ColorInputWidget(this);
+                        this.colorInput.on("change:color", this, this.color_changed);
+                        this.colorInput.appendTo(this.$el);
+                    },
+                    color_changed: function() {
+                        this.$el.find(".oe_color_div").css("background-color", this.colorInput.get("color"));
+                    },
+                });
+
+                instance.web.client_actions.add('petstore.homepage', 'instance.oepetstore.HomePage');
+            }
+
+        .. code-block:: xml
+
+            <?xml version="1.0" encoding="UTF-8"?>
+
+            <templates xml:space="preserve">
+                <t t-name="ColorInputWidget">
+                    <div>
+                        Red: <input type="text" class="oe_color_red" value="00"></input><br />
+                        Green: <input type="text" class="oe_color_green" value="00"></input><br />
+                        Blue: <input type="text" class="oe_color_blue" value="00"></input><br />
+                    </div>
+                </t>
+                <t t-name="HomePage">
+                    <div>
+                        <div class="oe_color_div"></div>
+                    </div>
+                </t>
+            </templates>
+
+        .. code-block:: css
+
+            .oe_color_div {
+                width: 100px;
+                height: 100px;
+                margin: 10px;
+            }
+
+        .. note::
+
+            jQuery's ``css()`` method allows setting a css property.
+
+Widget Helpers
+--------------
+
+We've seen the basics of the :class:`~openerp.web.Widget` class, QWeb and the
+events/properties system. There are still some more useful methods proposed by
+this class.
+
+``Widget``'s jQuery Selector
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+It is very common to need to select a precise element inside a widget. In the
+previous part of this guide we've seen a lot of uses of the ``find()`` method
+of jQuery objects::
+
+    this.$el.find("input.my_input")...
+
+:class:`~openerp.web.Widget` provides a shorter syntax that does the same
+thing with the :func:`~openerp.web.Widget.$` method::
+
+    instance.oepetstore.MyWidget = instance.web.Widget.extend({
+        start: function() {
+            this.$("input.my_input")...
+        },
+    });
+
+.. note::
+
+    We strongly advise you against using directly the global jQuery function
+    ``$()`` like we did in the previous chapter were we explained the jQuery
+    library and jQuery selectors. That type of global selection is sufficient
+    for simple applications but is not a good idea in real, big web
+    applications. The reason is simple: when you create a new type of widget
+    you never know how many times it will be instantiated. Since the ``$()``
+    global function operates in *the whole HTML displayed in the browser*, if
+    you instantiate a widget 2 times and use that function you will
+    incorrectly select the content of another instance of your widget. That's
+    why you must restrict the jQuery selections to HTML which is located
+    *inside* your widget most of the time.
+
+    Applying the same logic, you can also guess it is a very bad idea to try
+    to use HTML ids in any widget. If the widget is instantiated 2 times you
+    will have 2 different HTML element in the whole application that have the
+    same
+    id. And that is an error by itself. So you should stick to CSS classes to mark your HTML elements in all cases.
+
+Easier DOM Events Binding
+%%%%%%%%%%%%%%%%%%%%%%%%%
+
+In the previous part, we had to bind a lot of HTML element events like
+``click()`` or ``change()``. Now that we have the ``$()`` method to simplify
+code a little, let's see how it would look like::
+
+    instance.oepetstore.MyWidget = instance.web.Widget.extend({
+        start: function() {
+            var self = this;
+            this.$(".my_button").click(function() {
+                self.button_clicked();
+            });
+        },
+        button_clicked: function() {
+            ..
+        },
+    });
+
+It's still a bit long to type. That's why there is an even more simple syntax
+for that::
+
+    instance.oepetstore.MyWidget = instance.web.Widget.extend({
+        events: {
+            "click .my_button": "button_clicked",
+        },
+        button_clicked: function() {
+            ..
+        }
+    });
+
+.. warning::
+
+    It's important to differentiate the jQuery events that are triggered on
+    DOM elements and events of the widgets. The ``event`` class attribute *is
+    a helper to help binding jQuery events*, it has nothing to do with the
+    widget events that can be binded using the ``on()`` method.
+
+The ``event`` class attribute is a dictionary that allows to define jQuery
+events with a shorter syntax.
+
+The key is a string with 2 different parts separated with a space. The first
+part is the name of the event, the second one is the jQuery selector. So the
+key ``click .my_button`` will bind the event ``click`` on the elements
+matching the selector ``my_button``.
+
+The value is a string with the name of the method to call on the current
+object.
+
+Development Guidelines
+%%%%%%%%%%%%%%%%%%%%%%
+
+As explained in the prerequisites to read this guide, you should already know
+HTML and CSS. But developing web applications in JavaScript or developing web
+modules for Odoo require to be more strict than you will usually be when
+simply creating static web pages with CSS to style them. So these guidelines
+should be followed if you want to have manageable projects and avoid bugs or
+common mistakes:
+
+* Identifiers (``id`` attribute) should be avoided. In generic applications
+  and modules, ``id`` limits the re-usability of components and tends to make
+  code more brittle. Just about all the time, they can be replaced with
+  nothing, with classes or with keeping a reference to a DOM node or a jQuery
+  element around.
+
+  .. note::
+
+      If it is absolutely necessary to have an ``id`` (because a third-party
+      library requires one and can't take a DOM element), it should be
+      generated with ``_.uniqueId()``.
+
+* Avoid predictable/common CSS class names. Class names such as "content" or
+  "navigation" might match the desired meaning/semantics, but it is likely an
+  other developer will have the same need, creating a naming conflict and
+  unintended behavior. Generic class names should be prefixed with e.g. the
+  name of the component they belong to (creating "informal" namespaces, much
+  as in C or Objective-C).
+
+* Global selectors should be avoided. Because a component may be used several
+  times in a single page (an example in Odoo is dashboards), queries should be
+  restricted to a given component's scope. Unfiltered selections such as
+  ``$(selector)`` or ``document.querySelectorAll(selector)`` will generally
+  lead to unintended or incorrect behavior.  Odoo Web's
+  :class:`~openerp.web.Widget` has an attribute providing its DOM root
+  (:attr:`~openerp.web.Widget.$el`), and a shortcut to select nodes directly
+  (:func:`~openerp.web.Widget.$`).
+
+* More generally, never assume your components own or controls anything beyond
+  its own personal :attr:`~openerp.web.Widget.$el`
+
+* html templating/rendering should use QWeb unless absolutely trivial.
+
+* All interactive components (components displaying information to the screen
+  or intercepting DOM events) must inherit from Widget and correctly implement
+  and use its API and life cycle.
+
+Modify Existent Widgets and Classes
+-----------------------------------
+
+The class system of the Odoo web framework allows direct modification of
+existing classes using the :func:`~openerp.web.Widget.include` method of a
+class::
+
+    var TestClass = instance.web.Class.extend({
+        testMethod: function() {
+            return "hello";
+        },
+    });
+
+    TestClass.include({
+        testMethod: function() {
+            return this._super() + " world";
+        },
+    });
+
+    console.log(new TestClass().testMethod());
+    // will print "hello world"
+
+This system is similar to the inheritance mechanism, except it will directly
+modify the class. You can call ``this._super()`` to call the original
+implementation of the methods you are redefining. If the class already had
+sub-classes, all calls to ``this._super()`` in sub-classes will call the new
+implementations defined in the call to ``include()``. This will also work if
+some instances of the class (or of any of its sub-classes) were created prior
+to the call to :func:`~openerp.web.Widget.include`.
+
+.. warning::
+
+    Please note that, even if :func:`~openerp.web.Widget.include` can be a
+    powerful tool, it's not considered a very good programming practice
+    because it can easily create problems if used in a wrong way. So you
+    should use it to modify the behavior of an existing component only when
+    there are no other options, and try to limit its usages to the strict
+    minimum.
+
+Translations
+------------
+
+The process to translate text in Python and JavaScript code is very
+similar. You could have noticed these lines at the beginning of the
+``petstore.js`` file:
+
+    var _t = instance.web._t,
+        _lt = instance.web._lt;
+
+These lines are simply used to import the translation functions in the current
+JavaScript module. The correct to use them is this one::
+
+    this.$el.text(_t("Hello dear user!"));
+
+In Odoo, translations files are automatically generated by scanning the source
+code. All piece of code that calls a certain function are detected and their
+content is added to a translation file that will then be sent to the
+translators. In Python, the function is ``_()``. In JavaScript the function is
+:func:`~openerp.web._t` (and also :func:`~openerp.web._lt`).
+
+If the source file as never been scanned and the translation files does not
+contain any translation for the text given to ``_t()`` it will return the text
+as-is. If there is a translation it will return it.
+
+:func:`~openerp.web._lt` does almost the exact same thing but is a little bit
+more complicated. It does not return a text but returns a function that will
+return the text. It is reserved for very special cases::
+
+    var text_func = _lt("Hello dear user!");
+    this.$el.text(text_func());
+
+To have more information about Odoo's translations, please take a look at the
+reference documentation: https://doc.openerp.com/contribute/translations/ .
+
+Communication with the Odoo Server
+-------------------------------------
+
+Now you should know everything you need to display any type of graphical user
+interface with your Odoo modules.  Still, Odoo is a database-centric
+application so it's still not very useful if you can't query data from the
+database.
+
+As a reminder, in Odoo you are not supposed to directly query data from the
+PostgreSQL database, you will always use the build-in ORM (Object-Relational
+Mapping) and more precisely the Odoo *models*.
+
+Contacting Models
+%%%%%%%%%%%%%%%%%
+
+In the previous chapter we explained how to send HTTP requests to the web
+server using the ``$.ajax()`` method and the JSON format. It is useful to know
+how to make a JavaScript application communicate with its web server using
+these tools, but it's still a little bit low-level to be used in a complex
+application like Odoo.
+
+When the web client contacts the Odoo server it has to pass additional data
+like the necessary information to authenticate the current user. There is also
+some more complexity due to Odoo models that need a higher-level communication
+protocol to be used.
+
+This is why you will not use directly ``$.ajax()`` to communicate with the
+server. The web client framework provides classes to abstract that protocol.
+
+To demonstrate this, the file ``petstore.py`` already contains a small model
+with a sample method:
+
+.. code-block:: python
+
+    class message_of_the_day(osv.osv):
+        _name = "message_of_the_day"
+
+        def my_method(self, cr, uid, context=None):
+            return {"hello": "world"}
+
+        _columns = {
+            'message': fields.text(string="Message"),
+            'color': fields.char(string="Color", size=20),
+        }
+
+If you know Odoo models that code should be familiar to you. This model
+declares a table named ``message_of_the_day`` with two fields. It also has a
+method ``my_method()`` that doesn't do much except return a dictionary.
+
+Here is a sample widget that calls ``my_method()`` and displays the result::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            var self = this;
+            var model = new instance.web.Model("message_of_the_day");
+            model.call("my_method", [], {context: new instance.web.CompoundContext()}).then(function(result) {
+                self.$el.append("<div>Hello " + result["hello"] + "</div>");
+                // will show "Hello world" to the user
+            });
+        },
+    });
+
+The class used to contact Odoo models is ``instance.web.Model``. When you
+instantiate it, you must give as first argument to its constructor the name of
+the model you want to contact in Odoo. (Here it is ``message_of_the_day``, the
+model created for this example, but it could be any other model like
+``res.partner``.)
+
+:func:`~openerp.web.Model.call` is the method of :class:`~openerp.web.Model`
+used to call any method of an Odoo server-side model. Here are its arguments:
+
+* ``name`` is the name of the method to call on the model. Here it is the
+  method named ``my_method``.
+* ``args`` is a list of positional arguments to give to the method. The sample
+  ``my_method()`` method does not contain any particular argument we want to
+  give to it, so here is another example:
+
+  .. code-block:: python
+
+      def my_method2(self, cr, uid, a, b, c, context=None): ...
+
+  .. code-block:: javascript
+
+      model.call("my_method", [1, 2, 3], ...
+      // with this a=1, b=2 and c=3
+
+* ``kwargs`` is a list of named arguments to give to the method. In the
+  example, we have one named argument which is a bit special:
+  ``context``. It's given a value that may seem very strange right now: ``new
+  instance.web.CompoundContext()``. The meaning of that argument will be
+  explained later. Right now you should just know the ``kwargs`` argument
+  allows to give arguments to the Python method by name instead of
+  position. Example:
+
+  .. code-block:: python
+
+      def my_method2(self, cr, uid, a, b, c, context=None): ...
+
+  .. code-block:: javascript
+
+      model.call("my_method", [], {a: 1, b: 2, c: 3, ...
+      // with this a=1, b=2 and c=3
+
+.. note::
+
+    If you take a look at the ``my_method()``'s declaration in Python, you can
+    see it has two arguments named ``cr`` and ``uid``:
+
+    .. code-block:: python
+
+        def my_method(self, cr, uid, context=None):
+
+    You could have noticed we do not give theses arguments to the server when
+    we call that method from JavaScript. That is because theses arguments that
+    have to be declared in all models' methods are never sent from the Odoo
+    client.  These arguments are added implicitly by the Odoo server. The
+    first one is an object called the *cursor* that allows communication with
+    the database. The second one is the id of the currently logged in user.
+
+:func:`~openerp.web.Widget.call` returns a deferred resolved with the value
+returned by the model's method as first argument. If you don't know what
+deferreds are, take a look at the previous chapter (the part about HTTP
+requests in jQuery).
+
+CompoundContext
+%%%%%%%%%%%%%%%
+
+In the previous part, we avoided to explain the strange ``context`` argument
+in the call to our model's method:
+
+.. code-block:: javascript
+
+    model.call("my_method", [], {context: new instance.web.CompoundContext()})
+
+In Odoo, models' methods should always have an argument named ``context``:
+
+.. code-block:: python
+
+    def my_method(self, cr, uid, context=None): ...
+
+The context is like a "magic" argument that the web client will always give to
+the server when calling a method. The context is a dictionary containing
+multiple keys. One of the most important key is the language of the user, used
+by the server to translate all the messages of the application. Another one is
+the time zone of the user, used to compute correctly dates and times if Odoo
+is used by people in different countries.
+
+The ``argument`` is necessary in all methods, because if we forget it bad
+things could happen (like the application not being translated
+correctly). That's why, when you call a model's method, you should always give
+it to that argument. The solution to achieve that is to use
+:class:`openerp.web.CompoundContext`.
+
+:class:`~openerp.web.CompoundContext` is a class used to pass the user's
+context (with language, time zone, etc...) to the server as well as adding new
+keys to the context (some models' methods use arbitrary keys added to the
+context). It is created by giving to its constructor any number of
+dictionaries or other :class:`~openerp.web.CompoundContext` instances. It will
+merge all those contexts before sending them to the server.
+
+.. code-block:: javascript
+
+    model.call("my_method", [], {context: new instance.web.CompoundContext({'new_key': 'key_value'})})
+
+.. code-block:: python
+
+    def display_context(self, cr, uid, context=None):
+        print context
+        // will print: {'lang': 'en_US', 'new_key': 'key_value', 'tz': 'Europe/Brussels', 'uid': 1}
+
+You can see the dictionary in the argument ``context`` contains some keys that
+are related to the configuration of the current user in Odoo plus the
+``new_key`` key that was added when instantiating
+:class:`~openerp.web.CompoundContext`.
+
+To resume, you should always add an instance of
+:class:`~openerp.web.CompoundContext` in all calls to a model's method.
+
+Queries
+%%%%%%%
+
+If you know Odoo module development, you should already know everything
+necessary to communicate with models and make them do what you want. But there
+is still a small helper that could be useful to you :
+:func:`~openerp.web.Model.query`.
+
+:func:`~openerp.web.Model.query` is a shortcut for the usual combination of
+:py:meth:`~openerp.models.Model.search` and
+::py:meth:`~openerp.models.Model.read` methods in Odoo models. It allows to
+:search records and get their data with a shorter syntax. Example::
+
+    model.query(['name', 'login', 'user_email', 'signature'])
+         .filter([['active', '=', true], ['company_id', '=', main_company]])
+         .limit(15)
+         .all().then(function (users) {
+        // do work with users records
+    });
+
+:func:`~openerp.web.Model.query` takes as argument a list of fields to query
+in the model. It returns an instance of the :class:`openerp.web.Query` class.
+
+:class:`~openerp.web.Query` is a class representing the query you are trying
+to construct before sending it to the server. It has multiple methods you can
+call to customize the query. All these methods will return the current
+instance of :class:`~openerp.web.Query`:
+
+* :func:`~openerp.web.Query.filter` allows to specify an Odoo *domain*. As a
+  reminder, a domain in Odoo is a list of conditions, each condition is a list
+  it self.
+* :func:`~openerp.web.Query.limit` sets a limit to the number of records
+  returned.
+
+When you have customized you query, you can call the
+:func:`~openerp.web.Query.all` method. It will performs the real query to the
+server and return a deferred resolved with the result. The result is the same
+thing return by the model's method :py:meth:`~openerp.models.Model.read` (a
+list of dictionaries containing the asked fields).
+
+Exercises
+---------
+
+.. exercise:: Message of the Day
+
+    Create a widget ``MessageOfTheDay`` that will display the message
+    contained in the last record of the ``message_of_the_day``. The widget
+    should query the message as soon as it is inserted in the DOM and display
+    the message to the user. Display that widget on the home page of the Odoo
+    Pet Store module.
+
+    .. only:: solutions
+
+        .. code-block:: javascript
+
+            openerp.oepetstore = function(instance) {
+                var _t = instance.web._t,
+                    _lt = instance.web._lt;
+                var QWeb = instance.web.qweb;
+
+                instance.oepetstore = {};
+
+                instance.oepetstore.HomePage = instance.web.Widget.extend({
+                    template: "HomePage",
+                    start: function() {
+                        var motd = new instance.oepetstore.MessageOfTheDay(this);
+                        motd.appendTo(this.$el);
+                    },
+                });
+
+                instance.web.client_actions.add('petstore.homepage', 'instance.oepetstore.HomePage');
+
+                instance.oepetstore.MessageOfTheDay = instance.web.Widget.extend({
+                    template: "MessageofTheDay",
+                    init: function() {
+                        this._super.apply(this, arguments);
+                    },
+                    start: function() {
+                        var self = this;
+                        new instance.web.Model("message_of_the_day").query(["message"]).first().then(function(result) {
+                            self.$(".oe_mywidget_message_of_the_day").text(result.message);
+                        });
+                    },
+                });
+
+            }
+
+        .. code-block:: xml
+
+            <?xml version="1.0" encoding="UTF-8"?>
+
+            <templates xml:space="preserve">
+                <t t-name="HomePage">
+                    <div class="oe_petstore_homepage">
+                    </div>
+                </t>
+                <t t-name="MessageofTheDay">
+                    <div class="oe_petstore_motd">
+                        <p class="oe_mywidget_message_of_the_day"></p>
+                    </div>
+                </t>
+            </templates>
+
+        .. code-block:: css
+
+            .oe_petstore_motd {
+                margin: 5px;
+                padding: 5px;
+                border-radius: 3px;
+                background-color: #F0EEEE;
+            }
+
+.. exercise:: Pet Toys List
+
+    Create a widget ``PetToysList`` that will display 5 toys on the home page
+    with their names and their images.
+
+    In this Odoo addon, the pet toys are not stored in a new table like for
+    the message of the day. They are in the table ``product.product``. If you
+    click on the menu item :menuselection:`Pet Store --> Pet Store --> Pet
+    Toys` you will be able to see them. Pet toys are identified by the
+    category named ``Pet Toys``. You could need to document yourself on the
+    model ``product.product`` to be able to create a domain to select pet toys
+    and not all the products.
+
+    To display the images of the pet toys, you should know that images in Odoo
+    can be queried from the database like any other fields, but you will
+    obtain a string containing Base64-encoded binary. There is a little trick
+    to display images in Base64 format in HTML:
+
+    .. code-block:: html
+
+        <img class="oe_kanban_image" src="data:image/png;base64,${replace this by base64}"></image>
+
+    The ``PetToysList`` widget should be displayed on the home page on the
+    right of the ``MessageOfTheDay`` widget. You will need to make some layout
+    with CSS to achieve this.
+
+    .. only:: solutions
+
+        .. code-block:: javascript
+
+            openerp.oepetstore = function(instance) {
+                var _t = instance.web._t,
+                    _lt = instance.web._lt;
+                var QWeb = instance.web.qweb;
+
+                instance.oepetstore = {};
+
+                instance.oepetstore.HomePage = instance.web.Widget.extend({
+                    template: "HomePage",
+                    start: function() {
+                        var pettoys = new instance.oepetstore.PetToysList(this);
+                        pettoys.appendTo(this.$(".oe_petstore_homepage_left"));
+                        var motd = new instance.oepetstore.MessageOfTheDay(this);
+                        motd.appendTo(this.$(".oe_petstore_homepage_right"));
+                    },
+                });
+
+                instance.web.client_actions.add('petstore.homepage', 'instance.oepetstore.HomePage');
+
+                instance.oepetstore.MessageOfTheDay = instance.web.Widget.extend({
+                    template: "MessageofTheDay",
+                    init: function() {
+                        this._super.apply(this, arguments);
+                    },
+                    start: function() {
+                        var self = this;
+                        new instance.web.Model("message_of_the_day").query(["message"]).first().then(function(result) {
+                            self.$(".oe_mywidget_message_of_the_day").text(result.message);
+                        });
+                    },
+                });
+
+                instance.oepetstore.PetToysList = instance.web.Widget.extend({
+                    template: "PetToysList",
+                    start: function() {
+                        var self = this;
+                        new instance.web.Model("product.product").query(["name", "image"])
+                            .filter([["categ_id.name", "=", "Pet Toys"]]).limit(5).all().then(function(result) {
+                            _.each(result, function(item) {
+                                var $item = $(QWeb.render("PetToy", {item: item}));
+                                self.$el.append($item);
+                            });
+                        });
+                    },
+                });
+
+            }
+
+        .. code-block:: xml
+
+            <?xml version="1.0" encoding="UTF-8"?>
+
+            <templates xml:space="preserve">
+                <t t-name="HomePage">
+                    <div class="oe_petstore_homepage">
+                        <div class="oe_petstore_homepage_left"></div>
+                        <div class="oe_petstore_homepage_right"></div>
+                    </div>
+                </t>
+                <t t-name="MessageofTheDay">
+                    <div class="oe_petstore_motd">
+                        <p class="oe_mywidget_message_of_the_day"></p>
+                    </div>
+                </t>
+                <t t-name="PetToysList">
+                    <div class="oe_petstore_pettoyslist">
+                    </div>
+                </t>
+                <t t-name="PetToy">
+                    <div class="oe_petstore_pettoy">
+                        <p><t t-esc="item.name"/></p>
+                        <p><img t-att-src="'data:image/jpg;base64,'+item.image"/></p>
+                    </div>
+                </t>
+            </templates>
+
+        .. code-block:: css
+
+            .oe_petstore_homepage {
+                display: table;
+            }
+
+            .oe_petstore_homepage_left {
+                display: table-cell;
+                width : 300px;
+            }
+
+            .oe_petstore_homepage_right {
+                display: table-cell;
+                width : 300px;
+            }
+
+            .oe_petstore_motd {
+                margin: 5px;
+                padding: 5px;
+                border-radius: 3px;
+                background-color: #F0EEEE;
+            }
+
+            .oe_petstore_pettoyslist {
+                padding: 5px;
+            }
+
+            .oe_petstore_pettoy {
+                margin: 5px;
+                padding: 5px;
+                border-radius: 3px;
+                background-color: #F0EEEE;
+            }
+
+
+Existing web components
+-----------------------
+
+In the previous part, we explained the Odoo web framework, a development
+framework to create and architecture graphical JavaScript applications. The
+current part is dedicated to the existing components of the Odoo web client
+and most notably those containing entry points for developers to create new
+widgets that will be inserted inside existing views or components.
+
+The Action Manager
+%%%%%%%%%%%%%%%%%%
+
+To display a view or show a popup, as example when you click on a menu button,
+Odoo use the concept of actions.  Actions are pieces of information explaining
+what the web client should do. They can be loaded from the database or created
+on-the-fly. The component handling actions in the web client is the *Action
+Manager*.
+
+Using the Action Manager
+''''''''''''''''''''''''
+
+A way to launch an action is to use a menu element targeting an action
+registered in the database. As a reminder, here is how is defined a typical
+action and its associated menu item:
+
+.. code-block:: xml
+
+    <record model="ir.actions.act_window" id="message_of_the_day_action">
+        <field name="name">Message of the day</field>
+        <field name="res_model">message_of_the_day</field>
+        <field name="view_type">form</field>
+        <field name="view_mode">tree,form</field>
+    </record>
+
+    <menuitem id="message_day" name="Message of the day" parent="petstore_menu"
+        action="message_of_the_day_action"/>
+
+It is also possible to ask the Odoo client to load an action from a JavaScript
+code. To do so you have to create a dictionary explaining the action and then
+to ask the action manager to re-dispatch the web client to the new action.  To
+send a message to the action manager, :class:`~openerp.web.Widget` has a
+shortcut that will automatically find the current action manager and execute
+the action. Here is an example call to that method::
+
+    instance.web.TestWidget = instance.web.Widget.extend({
+        dispatch_to_new_action: function() {
+            this.do_action({
+                type: 'ir.actions.act_window',
+                res_model: "product.product",
+                res_id: 1,
+                views: [[false, 'form']],
+                target: 'current',
+                context: {},
+            });
+        },
+    });
+
+The method to call to ask the action manager to execute a new action is
+:func:`~openerp.web.Widget.do_action`. It receives as argument a dictionary
+defining the properties of the action. Here is a description of the most usual
+properties (not all of them may be used by all type of actions):
+
+* ``type``: The type of the action, which means the name of the model in which
+  the action is stored. As example, use ``ir.actions.act_window`` to show
+  views and ``ir.actions.client`` for client actions.
+* ``res_model``: For ``act_window`` actions, it is the model used by the
+  views.
+* ``res_id``: The ``id`` of the record to display.
+* ``views``: For ``act_window`` actions, it is a list of the views to
+  display. This argument must be a list of tuples with two components. The
+  first one must be the identifier of the view (or ``false`` if you just want
+  to use the default view defined for the model). The second one must be the
+  type of the view.
+* ``target``: If the value is ``current``, the action will be opened in the
+  main content part of the web client. The current action will be destroyed
+  before loading the new one. If it is ``new``, the action will appear in a
+  popup and the current action will not be destroyed.
+* ``context``: The context to use.
+
+.. exercise:: Jump to Product
+
+    Modify the ``PetToysList`` component developed in the previous part to
+    jump to a form view displaying the shown item when we click on the item in
+    the list.
+
+    .. only:: solutions
+
+        .. code-block:: javascript
+
+            instance.oepetstore.PetToysList = instance.web.Widget.extend({
+                template: "PetToysList",
+                start: function() {
+                    var self = this;
+                    new instance.web.Model("product.product").query(["name", "image"])
+                        .filter([["categ_id.name", "=", "Pet Toys"]]).limit(5).all().then(function(result) {
+                        _.each(result, function(item) {
+                            var $item = $(QWeb.render("PetToy", {item: item}));
+                            self.$el.append($item);
+                            $item.click(function() {
+                                self.item_clicked(item);
+                            });
+                        });
+                    });
+                },
+                item_clicked: function(item) {
+                    this.do_action({
+                        type: 'ir.actions.act_window',
+                        res_model: "product.product",
+                        res_id: item.id,
+                        views: [[false, 'form']],
+                        target: 'current',
+                        context: {},
+                    });
+                },
+            });
+
+Client Actions
+%%%%%%%%%%%%%%
+
+In the module installed during the previous part of this guide, we defined a
+simple widget that was displayed when we clicked on a menu element. This is
+because this widget was registered as a *client action*. Client actions are a
+type of action that are completely defined by JavaScript code. Here is a
+reminder of the way we defined this client action::
+
+    instance.oepetstore.HomePage = instance.web.Widget.extend({
+        start: function() {
+            console.log("pet store home page loaded");
+        },
+    });
+
+    instance.web.client_actions.add('petstore.homepage', 'instance.oepetstore.HomePage');
+
+``instance.web.client_actions`` is an instance of the
+:class:`~openerp.web.Registry` class. Registries are not very different to
+simple dictionaries, except they assign strings to class names. Adding the
+``petstore.homepage`` key to this registry simply tells the web client "If
+someone asks you to open a client action with key ``petstore.homepage``,
+instantiate the ``instance.oepetstore.HomePage`` class and show it to the
+user".
+
+Here is how the menu element to show this client action was defined:
+
+.. code-block:: xml
+
+    <record id="action_home_page" model="ir.actions.client">
+        <field name="tag">petstore.homepage</field>
+    </record>
+
+    <menuitem id="home_page_petstore_menu" name="Home Page" parent="petstore_menu"
+        action="action_home_page"/>
+
+Client actions do not need a lot of information except their type, which is
+stored in the ``tag`` field.
+
+When the web client wants to display a client action, it will simply show it
+in the main content block of the web client. This is completely sufficient to
+allow the widget to display anything and so create a completely new feature
+for the web client.
+
+Architecture of the Views
+%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Most of the complexity of the web client resides in views. They are the basic
+tools to display the data in the database.  The part will explain the views
+and how those are displayed in the web client.
+
+The View Manager
+''''''''''''''''
+
+Previously we already explained the purpose of the *Action Manager*. It is a
+component, whose class is ``ActionManager``, that will handle the Odoo actions
+(notably the actions associated with menu buttons).
+
+When an ``ActionManager`` instance receive an action with type
+``ir.actions.act_window``, it knows it has to show one or more views
+associated with a precise model. To do so, it creates a *View Manager* that
+will create one or multiple *Views*. See this diagram:
+
+.. image:: web/viewarchitecture.*
+   :align: center
+   :width: 40%
+
+The ``ViewManager`` instance will instantiate each view class corresponding to
+the views indicated in the ``ir.actions.act_window`` action. As example, the
+class corresponding to the view type ``form`` is ``FormView``. Each view class
+inherits the ``View`` abstract class.
+
+The Views
+'''''''''
+
+All the typical type of views in Odoo (all those you can switch to using the
+small buttons under the search input text) are represented by a class
+extending the ``View`` abstract class. Note the *Search View* (the search
+input text on the top right of the screen that typically appear in kanban and
+list views) is also considered a type of view even if it doesn't work like the
+others (you can not "switch to" the search view and it doesn't take the full
+screen).
+
+A view has the responsibility to load its XML view description from the server
+and display it. Views are also given an instance of the ``DataSet``
+class. That class contains a list of identifiers corresponding to records that
+the view should display. It is filled by the search view and the current view
+is supposed to display the result of each search after it was performed by the
+search view.
+
+The Form View Fields
+%%%%%%%%%%%%%%%%%%%%
+
+A typical need in the web client is to extend the form view to display more
+specific widgets. One of the possibilities to do this is to define a new type
+of *Field*.
+
+A field, in the form view, is a type of widget designed to display and edit
+the content of *one (and only one) field* in a single record displayed by the
+form view. All data types available in models have a default implementation to
+display and edit them in the form view. As example, the ``FieldChar`` class
+allows to edit the ``char`` data type.
+
+Other field classes simply provide an alternative widget to represent an
+existing data type. A good example of this is the ``FieldEmail`` class. There
+is no ``email`` type in the models of Odoo. That class is designed to display
+a ``char`` field assuming it contains an email (it will show a clickable link
+to directly send a mail to the person and will also check the validity of the
+mail address).
+
+Also note there is nothing that disallow a field class to work with more than
+one data type. As example, the ``FieldSelection`` class works with both
+``selection`` and ``many2one`` field types.
+
+As a reminder, to indicate a precise field type in a form view XML
+description, you just have to specify the ``widget`` attribute:
+
+.. code-block:: xml
+
+    <field name="contact_mail" widget="email"/>
+
+It is also a good thing to notice that the form view field classes are also
+used in the editable list views. So, by defining a new field class, it make
+this new widget available in both views.
+
+Another type of extension mechanism for the form view is the *Form Widget*,
+which has fewer restrictions than the fields (even though it can be more
+complicated to implement). Form widgets will be explained later in this guide.
+
+Fields are instantiated by the form view after it has read its XML description
+and constructed the corresponding HTML representing that description. After
+that, the form view will communicate with the field objects using some
+methods. Theses methods are defined by the ``FieldInterface``
+interface. Almost all fields inherit the ``AbstractField`` abstract
+class. That class defines some default mechanisms that need to be implemented
+by most fields.
+
+Here are some of the responsibilities of a field class:
+
+* The field class must display and allow the user to edit the value of the field.
+* It must correctly implement the 3 field attributes available in all fields
+  of Odoo. The ``AbstractField`` class already implements an algorithm that
+  dynamically calculates the value of these attributes (they can change at any
+  moment because their value change according to the value of other
+  fields). Their values are stored in *Widget Properties* (the widget
+  properties were explained earlier in this guide). It is the responsibility
+  of each field class to check these widget properties and dynamically adapt
+  depending of their values. Here is a description of each of these
+  attributes:
+
+  * ``required``: The field must have a value before saving. If ``required``
+    is ``true`` and the field doesn't have a value, the method
+    ``is_valid()`` of the field must return ``false``.
+  * ``invisible``: When this is ``true``, the field must be invisible. The
+    ``AbstractField`` class already has a basic implementation of this
+    behavior that fits most fields.
+  * ``readonly``: When ``true``, the field must not be editable by the
+    user. Most fields in Odoo have a completely different behavior depending
+    on the value of ``readonly``. As example, the ``FieldChar`` displays an
+    HTML ``<input>`` when it is editable and simply displays the text when
+    it is read-only. This also means it has much more code it would need to
+    implement only one behavior, but this is necessary to ensure a good user
+    experience.
+
+* Fields have two methods, ``set_value()`` and ``get_value()``, which are
+  called by the form view to give it the value to display and get back the new
+  value entered by the user. These methods must be able to handle the value as
+  given by the Odoo server when a ``read()`` is performed on a model and give
+  back a valid value for a ``write()``.  Remember that the JavaScript/Python
+  data types used to represent the values given by ``read()`` and given to
+  ``write()`` is not necessarily the same in Odoo. As example, when you read a
+  many2one, it is always a tuple whose first value is the id of the pointed
+  record and the second one is the name get (ie: ``(15, "Agrolait")``). But
+  when you write a many2one it must be a single integer, not a tuple
+  anymore. ``AbstractField`` has a default implementation of these methods
+  that works well for simple data type and set a widget property named
+  ``value``.
+
+Please note that, to better understand how to implement fields, you are
+strongly encouraged to look at the definition of the ``FieldInterface``
+interface and the ``AbstractField`` class directly in the code of the Odoo web
+client.
+
+Creating a New Type of Field
+''''''''''''''''''''''''''''
+
+In this part we will explain how to create a new type of field. The example
+here will be to re-implement the ``FieldChar`` class and explain progressively
+each part.
+
+Simple Read-Only Field
+""""""""""""""""""""""
+
+Here is a first implementation that will only be able to display a text. The
+user will not be able to modify the content of the field.
+
+.. code-block:: javascript
+
+    instance.oepetstore.FieldChar2 = instance.web.form.AbstractField.extend({
+        init: function() {
+            this._super.apply(this, arguments);
+            this.set("value", "");
+        },
+        render_value: function() {
+            this.$el.text(this.get("value"));
+        },
+    });
+
+    instance.web.form.widgets.add('char2', 'instance.oepetstore.FieldChar2');
+
+In this example, we declare a class named ``FieldChar2`` inheriting from
+``AbstractField``. We also register this class in the registry
+``instance.web.form.widgets`` under the key ``char2``. That will allow us to
+use this new field in any form view by specifying ``widget="char2"`` in the
+``<field/>`` tag in the XML declaration of the view.
+
+In this example, we define a single method: ``render_value()``. All it does is
+display the widget property ``value``.  Those are two tools defined by the
+``AbstractField`` class. As explained before, the form view will call the
+method ``set_value()`` of the field to set the value to display. This method
+already has a default implementation in ``AbstractField`` which simply sets
+the widget property ``value``. ``AbstractField`` also watch the
+``change:value`` event on itself and calls the ``render_value()`` when it
+occurs. So, ``render_value()`` is a convenience method to implement in child
+classes to perform some operation each time the value of the field changes.
+
+In the ``init()`` method, we also define the default value of the field if
+none is specified by the form view (here we assume the default value of a
+``char`` field should be an empty string).
+
+Read-Write Field
+""""""""""""""""
+
+Fields that only display their content and don't give the possibility to the
+user to modify it can be useful, but most fields in Odoo allow edition
+too. This makes the field classes more complicated, mostly because fields are
+supposed to handle both and editable and non-editable mode, those modes are
+often completely different (for design and usability purpose) and the fields
+must be able to switch from one mode to another at any moment.
+
+To know in which mode the current field should be, the ``AbstractField`` class
+sets a widget property named ``effective_readonly``. The field should watch
+the changes in that widget property and display the correct mode
+accordingly. Example::
+
+    instance.oepetstore.FieldChar2 = instance.web.form.AbstractField.extend({
+        init: function() {
+            this._super.apply(this, arguments);
+            this.set("value", "");
+        },
+        start: function() {
+            this.on("change:effective_readonly", this, function() {
+                this.display_field();
+                this.render_value();
+            });
+            this.display_field();
+            return this._super();
+        },
+        display_field: function() {
+            var self = this;
+            this.$el.html(QWeb.render("FieldChar2", {widget: this}));
+            if (! this.get("effective_readonly")) {
+                this.$("input").change(function() {
+                    self.internal_set_value(self.$("input").val());
+                });
+            }
+        },
+        render_value: function() {
+            if (this.get("effective_readonly")) {
+                this.$el.text(this.get("value"));
+            } else {
+                this.$("input").val(this.get("value"));
+            }
+        },
+    });
+
+    instance.web.form.widgets.add('char2', 'instance.oepetstore.FieldChar2');
+
+.. code-block:: xml
+
+    <t t-name="FieldChar2">
+        <div class="oe_field_char2">
+            <t t-if="! widget.get('effective_readonly')">
+                <input type="text"></input>
+            </t>
+        </div>
+    </t>
+
+In the ``start()`` method (which is called right after a widget has been
+appended to the DOM), we bind on the event ``change:effective_readonly``. That
+will allow use to redisplay the field each time the widget property
+``effective_readonly`` changes. This event handler will call
+``display_field()``, which is also called directly in ``start()``. This
+``display_field()`` was created specifically for this field, it's not a method
+defined in ``AbstractField`` or any other class. This is the method we will
+use to display the content of the field depending we are in read-only mode or
+not.
+
+From now on the conception of this field is quite typical, except there is a
+lot of verifications to know the state of the ``effective_readonly`` property:
+
+* In the QWeb template used to display the content of the widget, it displays
+  an ``<input type="text" />`` if we are in read-write mode and nothing in
+  particular in read-only mode.
+* In the ``display_field()`` method, we have to bind on the ``change`` event
+  of the ``<input type="text" />`` to know when the user has changed the
+  value. When it happens, we call the ``internal_set_value()`` method with the
+  new value of the field. This is a convenience method provided by the
+  ``AbstractField`` class. That method will set a new value in the ``value``
+  property but will not trigger a call to ``render_value()`` (which is not
+  necessary since the ``<input type="text" />`` already contains the correct
+  value).
+* In ``render_value()``, we use a completely different code to display the
+  value of the field depending if we are in read-only or in read-write mode.
+
+.. exercise:: Create a Color Field
+
+    Create a ``FieldColor`` class. The value of this field should be a string
+    containing a color code like those used in CSS (example: ``#FF0000`` for
+    red). In read-only mode, this color field should display a little block
+    whose color corresponds to the value of the field. In read-write mode, you
+    should display an ``<input type="color" />``. That type of ``<input />``
+    is an HTML5 component that doesn't work in all browsers but works well in
+    Google Chrome. So it's OK to use as an exercise.
+
+    You can use that widget in the form view of the ``message_of_the_day``
+    model for its field named ``color``. As a bonus, you can change the
+    ``MessageOfTheDay`` widget created in the previous part of this guide to
+    display the message of the day with the background color indicated in the
+    ``color`` field.
+
+    .. only:: solutions
+
+        .. code-block:: javascript
+
+            instance.oepetstore.FieldColor = instance.web.form.AbstractField.extend({
+                init: function() {
+                    this._super.apply(this, arguments);
+                    this.set("value", "");
+                },
+                start: function() {
+                    this.on("change:effective_readonly", this, function() {
+                        this.display_field();
+                        this.render_value();
+                    });
+                    this.display_field();
+                    return this._super();
+                },
+                display_field: function() {
+                    var self = this;
+                    this.$el.html(QWeb.render("FieldColor", {widget: this}));
+                    if (! this.get("effective_readonly")) {
+                        this.$("input").change(function() {
+                            self.internal_set_value(self.$("input").val());
+                        });
+                    }
+                },
+                render_value: function() {
+                    if (this.get("effective_readonly")) {
+                        this.$(".oe_field_color_content").css("background-color", this.get("value") || "#FFFFFF");
+                    } else {
+                        this.$("input").val(this.get("value") || "#FFFFFF");
+                    }
+                },
+            });
+
+            instance.web.form.widgets.add('color', 'instance.oepetstore.FieldColor');
+
+        .. code-block:: xml
+
+            <t t-name="FieldColor">
+                <div class="oe_field_color">
+                    <t t-if="widget.get('effective_readonly')">
+                        <div class="oe_field_color_content" />
+                    </t>
+                    <t t-if="! widget.get('effective_readonly')">
+                        <input type="color"></input>
+                    </t>
+                </div>
+            </t>
+
+        .. code-block:: css
+
+            .oe_field_color_content {
+                height: 20px;
+                width: 50px;
+                border: 1px solid black;
+            }
+
+The Form View Custom Widgets
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Form fields can be useful, but their purpose is to edit a single field. To
+interact with the whole form view and have more liberty to integrate new
+widgets in it, it is recommended to create a custom form widget.
+
+Custom form widgets are widgets that can be added in any form view using a
+specific syntax in the XML definition of the view. Example:
+
+.. code-block:: xml
+
+    <widget type="xxx" />
+
+This type of widget will simply be created by the form view during the
+creation of the HTML according to the XML definition. They have properties in
+common with the fields (like the ``effective_readonly`` property) but they are
+not assigned a precise field. And so they don't have methods like
+``get_value()`` and ``set_value()``. They must inherit from the ``FormWidget``
+abstract class.
+
+The custom form widgets can also interact with the fields of the form view by
+getting or setting their values using the ``field_manager`` attribute of
+``FormWidget``. Here is an example usage::
+
+    instance.oepetstore.WidgetMultiplication = instance.web.form.FormWidget.extend({
+        start: function() {
+            this._super();
+            this.field_manager.on("field_changed:integer_a", this, this.display_result);
+            this.field_manager.on("field_changed:integer_b", this, this.display_result);
+            this.display_result();
+        },
+        display_result: function() {
+            var result = this.field_manager.get_field_value("integer_a") *
+                this.field_manager.get_field_value("integer_b");
+            this.$el.text("a*b = " + result);
+        }
+    });
+
+    instance.web.form.custom_widgets.add('multiplication', 'instance.oepetstore.WidgetMultiplication');
+
+This example custom widget is designed to take the values of two existing
+fields (those must exist in the form view) and print the result of their
+multiplication. It also refreshes each time the value of any of those fields
+changes.
+
+The ``field_manager`` attribute is in fact the ``FormView`` instance
+representing the form view. The methods that widgets can call on that form
+view are documented in the code of the web client in the ``FieldManagerMixin``
+interface.  The most useful features are:
+
+* The method ``get_field_value()`` which returns the value of a field.
+* When the value of a field is changed, for any reason, the form view will
+  trigger an event named ``field_changed:xxx`` where ``xxx`` is the name of
+  the field.
+* Also, it is possible to change the value of the fields using the method
+  ``set_values()``. This method takes a dictionary as first and only argument
+  whose keys are the names of the fields to change and values are the new
+  values.
+
+.. exercise:: Show Coordinates on Google Map
+
+    In this exercise we would like to add two new fields on the
+    ``product.product`` model: ``provider_latitude`` and
+    ``provider_longitude``. Those would represent coordinates on a map. We
+    also would like you to create a custom widget able to display a map
+    showing these coordinates.
+
+    To display that map, you can simply use the Google Map service using an HTML code similar to this:
+
+    .. code-block:: html
+
+        <iframe width="400" height="300" src="https://maps.google.com/?ie=UTF8&amp;ll=XXX,YYY&amp;output=embed">
+        </iframe>
+
+    Just replace ``XXX`` with the latitude and ``YYY`` with the longitude.
+
+    You should display those two new fields as well as the map widget in a new
+    page of the notebook displayed in the product form view.
+
+    .. only:: solutions
+
+        .. code-block:: javascript
+
+            instance.oepetstore.WidgetCoordinates = instance.web.form.FormWidget.extend({
+                start: function() {
+                    this._super();
+                    this.field_manager.on("field_changed:provider_latitude", this, this.display_map);
+                    this.field_manager.on("field_changed:provider_longitude", this, this.display_map);
+                    this.display_map();
+                },
+                display_map: function() {
+                    this.$el.html(QWeb.render("WidgetCoordinates", {
+                        "latitude": this.field_manager.get_field_value("provider_latitude") || 0,
+                        "longitude": this.field_manager.get_field_value("provider_longitude") || 0,
+                    }));
+                }
+            });
+
+            instance.web.form.custom_widgets.add('coordinates', 'instance.oepetstore.WidgetCoordinates');
+
+        .. code-block:: xml
+
+            <t t-name="WidgetCoordinates">
+                <iframe width="400" height="300"
+                    t-att-src="'https://maps.google.com/?ie=UTF8&amp;ll=' + latitude + ',' + longitude + '&amp;output=embed'">
+                </iframe>
+            </t>
+
+.. exercise:: Get the Current Coordinate
+
+    Now we would like to display an additional button to automatically set the
+    coordinates to the location of the current user.
+
+    To get the coordinates of the user, an easy way is to use the geolocation
+    JavaScript API.  `See the online documentation to know how to use it`_.
+
+    .. _See the online documentation to know how to use it: http://www.w3schools.com/html/html5_geolocation.asp
+
+    Please also note that it wouldn't be very logical to allow the user to
+    click on that button when the form view is in read-only mode. So, this
+    custom widget should handle correctly the ``effective_readonly`` property
+    just like any field. One way to do this would be to make the button
+    disappear when ``effective_readonly`` is true.
+
+    .. only:: solutions
+
+        .. code-block:: javascript
+
+            instance.oepetstore.WidgetCoordinates = instance.web.form.FormWidget.extend({
+                start: function() {
+                    this._super();
+                    this.field_manager.on("field_changed:provider_latitude", this, this.display_map);
+                    this.field_manager.on("field_changed:provider_longitude", this, this.display_map);
+                    this.on("change:effective_readonly", this, this.display_map);
+                    this.display_map();
+                },
+                display_map: function() {
+                    var self = this;
+                    this.$el.html(QWeb.render("WidgetCoordinates", {
+                        "latitude": this.field_manager.get_field_value("provider_latitude") || 0,
+                        "longitude": this.field_manager.get_field_value("provider_longitude") || 0,
+                    }));
+                    this.$("button").toggle(! this.get("effective_readonly"));
+                    this.$("button").click(function() {
+                        navigator.geolocation.getCurrentPosition(_.bind(self.received_position, self));
+                    });
+                },
+                received_position: function(obj) {
+                    var la = obj.coords.latitude;
+                    var lo = obj.coords.longitude;
+                    this.field_manager.set_values({
+                        "provider_latitude": la,
+                        "provider_longitude": lo,
+                    });
+                },
+            });
+
+            instance.web.form.custom_widgets.add('coordinates', 'instance.oepetstore.WidgetCoordinates');
+
+        .. code-block:: xml
+
+            <t t-name="WidgetCoordinates">
+                <iframe width="400" height="300"
+                    t-att-src="'https://maps.google.com/?ie=UTF8&amp;ll=' + latitude + ',' + longitude + '&amp;output=embed'">
+                </iframe>
+                <button>Get My Current Coordinate</button>
+            </t>
+
+.. _jQuery: http://jquery.org
+.. _Underscore.js: http://underscorejs.org
diff --git a/doc/howtos/web/qweb.png b/doc/howtos/web/qweb.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e2ca376f3caa1dac908dd923564ab6e2a797369
GIT binary patch
literal 40390
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

literal 0
HcmV?d00001

diff --git a/doc/howtos/web/viewarchitecture.dia b/doc/howtos/web/viewarchitecture.dia
new file mode 100644
index 0000000000000000000000000000000000000000..0c28960a1ed86c5d1eeba6c2cd8a5b57cac27b97
GIT binary patch
literal 1918
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
TH2e}1zF)8GIp^t&<l*@n>nF=f

literal 0
HcmV?d00001

diff --git a/doc/howtos/web/viewarchitecture.png b/doc/howtos/web/viewarchitecture.png
new file mode 100644
index 0000000000000000000000000000000000000000..5fa403bb6ec9b423417024a8cc453f61ec197e46
GIT binary patch
literal 35268
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

literal 0
HcmV?d00001

diff --git a/doc/howtos/web/viewarchitecture.svg b/doc/howtos/web/viewarchitecture.svg
new file mode 100644
index 000000000000..7e5b97ccc86b
--- /dev/null
+++ b/doc/howtos/web/viewarchitecture.svg
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">
+<svg width="20cm" height="20cm" viewBox="301 86 387 399" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+  <g>
+    <rect style="fill: #ffffff" x="414" y="87" width="146.55" height="28"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="414" y="87" width="146.55" height="28"/>
+    <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="487.275" y="106">ActionManager</text>
+    <rect style="fill: #ffffff" x="414" y="115" width="146.55" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="414" y="115" width="146.55" height="8"/>
+    <rect style="fill: #ffffff" x="414" y="123" width="146.55" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="414" y="123" width="146.55" height="8"/>
+  </g>
+  <g>
+    <rect style="fill: #ffffff" x="460" y="320" width="53.25" height="28"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="460" y="320" width="53.25" height="28"/>
+    <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:italic;font-weight:700" x="486.625" y="339">View</text>
+    <rect style="fill: #ffffff" x="460" y="348" width="53.25" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="460" y="348" width="53.25" height="8"/>
+    <rect style="fill: #ffffff" x="460" y="356" width="53.25" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="460" y="356" width="53.25" height="8"/>
+  </g>
+  <g>
+    <rect style="fill: #ffffff" x="421" y="204" width="132.35" height="28"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="421" y="204" width="132.35" height="28"/>
+    <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="487.175" y="223">ViewManager</text>
+    <rect style="fill: #ffffff" x="421" y="232" width="132.35" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="421" y="232" width="132.35" height="8"/>
+    <rect style="fill: #ffffff" x="421" y="240" width="132.35" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="421" y="240" width="132.35" height="8"/>
+  </g>
+  <g>
+    <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="487.275,157.177 487.275,174.5 487.175,174.5 487.175,202.994 "/>
+    <polygon style="fill: #000000" points="487.275,132.006 492.075,146.006 487.275,160.006 482.475,146.006 "/>
+    <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="487.275,132.006 492.075,146.006 487.275,160.006 482.475,146.006 "/>
+    <text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="487.225" y="170.5"></text>
+    <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="498.275" y="144.006"></text>
+    <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="491.175" y="198.994">1</text>
+  </g>
+  <g>
+    <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="487.175,274.177 487.175,291 486.625,291 486.625,318.994 "/>
+    <polygon style="fill: #000000" points="487.175,249.006 491.975,263.006 487.175,277.006 482.375,263.006 "/>
+    <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="487.175,249.006 491.975,263.006 487.175,277.006 482.375,263.006 "/>
+    <text font-size="12.7998" style="fill: #000000;text-anchor:middle;font-family:monospace;font-style:normal;font-weight:normal" x="486.9" y="287"></text>
+    <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="498.175" y="261.006"></text>
+    <text font-size="12.7998" style="fill: #000000;text-anchor:start;font-family:monospace;font-style:normal;font-weight:normal" x="490.625" y="314.994">1..*</text>
+  </g>
+  <g>
+    <rect style="fill: #ffffff" x="302" y="440" width="99.1" height="28"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="302" y="440" width="99.1" height="28"/>
+    <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="351.55" y="459">FormView</text>
+    <rect style="fill: #ffffff" x="302" y="468" width="99.1" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="302" y="468" width="99.1" height="8"/>
+    <rect style="fill: #ffffff" x="302" y="476" width="99.1" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="302" y="476" width="99.1" height="8"/>
+  </g>
+  <g>
+    <rect style="fill: #ffffff" x="443.8" y="438.8" width="86.1" height="28"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="443.8" y="438.8" width="86.1" height="28"/>
+    <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="486.85" y="457.8">ListView</text>
+    <rect style="fill: #ffffff" x="443.8" y="466.8" width="86.1" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="443.8" y="466.8" width="86.1" height="8"/>
+    <rect style="fill: #ffffff" x="443.8" y="474.8" width="86.1" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="443.8" y="474.8" width="86.1" height="8"/>
+  </g>
+  <g>
+    <rect style="fill: #ffffff" x="564.8" y="438.8" width="121.5" height="28"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="564.8" y="438.8" width="121.5" height="28"/>
+    <text font-size="16" style="fill: #000000;text-anchor:middle;font-family:sans-serif;font-style:normal;font-weight:700" x="625.55" y="457.8">KanbanView</text>
+    <rect style="fill: #ffffff" x="564.8" y="466.8" width="121.5" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="564.8" y="466.8" width="121.5" height="8"/>
+    <rect style="fill: #ffffff" x="564.8" y="474.8" width="121.5" height="8"/>
+    <rect style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" x="564.8" y="474.8" width="121.5" height="8"/>
+  </g>
+  <g>
+    <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="486.625,382.236 486.625,410 351.55,410 351.55,440 "/>
+    <polygon style="fill: #ffffff" points="494.625,382.236 486.625,366.236 478.625,382.236 "/>
+    <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="494.625,382.236 486.625,366.236 478.625,382.236 "/>
+  </g>
+  <g>
+    <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="486.625,383.242 486.625,409.903 486.85,409.903 486.85,438.8 "/>
+    <polygon style="fill: #ffffff" points="494.625,383.242 486.625,367.242 478.625,383.242 "/>
+    <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="494.625,383.242 486.625,367.242 478.625,383.242 "/>
+  </g>
+  <g>
+    <polyline style="fill: none; fill-opacity:0; stroke-width: 2; stroke-dasharray: 8; stroke: #000000" points="486.625,383.242 486.625,409.903 625.55,409.903 625.55,438.8 "/>
+    <polygon style="fill: #ffffff" points="494.625,383.242 486.625,367.242 478.625,383.242 "/>
+    <polygon style="fill: none; fill-opacity:0; stroke-width: 2; stroke: #000000" points="494.625,383.242 486.625,367.242 478.625,383.242 "/>
+  </g>
+</svg>
diff --git a/doc/tutorials.rst b/doc/tutorials.rst
index 14607cfa050b..5cbfec9bae67 100644
--- a/doc/tutorials.rst
+++ b/doc/tutorials.rst
@@ -7,3 +7,4 @@ Tutorials
 
     howtos/website
     howtos/backend
+    howtos/web
-- 
GitLab