The view layer describes the user interface. Views are defined using XML, which is used by the web client framework to generate data-aware HTML views.

We have menu items that can activate actions that can render views. For example, the Users menu item processes an action also called Users, that in turn renders a series of views. There are several view types available, such as the list and form views, and the filter options made available are also defined by a particular type of view, the search view.

The Odoo development guidelines states that the XML files defining the user interface should be placed inside a views/ subdirectory.

Let's start creating the user interface for our To-Do application.

Now that we have a model to store our data, we should make it available on the user interface.

For that, we should add a menu option to open the To-do Task model so that it can be used.

Create the views/todo_menu.xml file to define a menu item and the action performed by it:

<?xml version="1.0"?> 
<odoo> 
  <!-- Action to open To-do Task list --> 
  <act_window id="action_todo_task" 
    name="To-do Task" 
    res_model="todo.task" 
    view_mode="tree,form" /> 
  <!-- Menu item to open To-do Task list --> 
  <menuitem id="menu_todo_task" 
    name="Todos" 
    action="action_todo_task" /> 
</odoo> 

The user interface, including menu options and actions, is stored in database tables. The XML file is a data file used to load those definitions into the database when the module is installed or upgraded. The preceding code is an Odoo data file, describing two records to add to Odoo:

Both elements include an id attribute. This id attribute also called an XML ID, is very important: it is used to uniquely identify each data element inside the module, and can be used by other elements to reference it. In this case, the <menuitem> element needs to reference the action to process, and needs to make use of the <act_window> ID for that. XML IDs are discussed in greater detail in Chapter 4Module Data.

Our module does not yet know about the new XML data file. This is done by adding it to the data attribute in the __manifest__.py file. It holds the list of files to be loaded by the module. Add this attribute to the manifest's dictionary:

'data': ['views/todo_menu.xml'], 

Now we need to upgrade the module again for these changes to take effect. Go to the Todos top menu and you should see our new menu option available:

Adding menu items

Even though we haven't defined our user interface view, clicking on the Todos menu will open an automatically generated form for our model, allowing us to add and edit records.

Odoo is nice enough to automatically generate them so that we can start working with our model right away.

So far, so good! Let's improve our user interface now. Try making gradual improvements as shown in the next sections, doing frequent module upgrades, and don't be afraid to experiment. You might also want to try the --dev=all server option. Using it the view definitions are read directly from the XML files so that your changes can be immediately available to Odoo without the need of a module upgrade.

Odoo supports several types of views, but the three most important ones are: tree (usually called list views), form, and search views. We'll add an example of each to our module.

When viewing a model in list mode, a <tree> view is used. Tree views are capable of displaying lines organized in hierarchies, but most of the time, they are used to display plain lists.

We can add the following tree view definition to todo_view.xml:

<record id="view_tree_todo_task" model="ir.ui.view"> 
  <field name="name">To-do Task Tree</field> 
  <field name="model">todo.task</field> 
  <field name="arch" type="xml"> 
    <tree colors="decoration-muted:is_done==True"> 
      <field name="name"/> 
      <field name="is_done"/> 
    </tree> 
  </field> 
</record> 

This defines a list with only two columns: name and is_done. We also added a nice touch: the lines for done tasks (is_done==True) are shown grayed out. This is done applying the Bootstrap class muted. Check http://getbootstrap.com/css/#helper-classes-colors for more information on Bootstrap and its contextual colors.

At the top-right corner of the list, Odoo displays a search box. The fields it searches in and the available filters are defined by a <search> view.

As before, we will add this to todo_view.xml:

<record id="view_filter_todo_task" model="ir.ui.view"> 
  <field name="name">To-do Task Filter</field> 
  <field name="model">todo.task</field> 
  <field name="arch" type="xml"> 
    <search> 
      <field name="name"/> 
      <filter string="Not Done" 
        domain="[('is_done','=',False)]"/> 
      <filter string="Done" 
        domain="[('is_done','!=',False)]"/> 
    </search> 
  </field> 
</record> 

The <field> elements define fields that are also searched when typing in the search box. The <filter> elements add predefined filter conditions, that can be toggled with a user click, defined using a specific syntax.