Skip to main content

Web pages and controllers



Web pages and controllers

Odoo also provides a web development framework, which can be used to develop website features closely integrated with our backend apps. We will take our first steps toward this by creating a simple web page to display the list of active books in our library. It will respond to web requests at the http://my-server/library/books address, so /library/books is the URL endpoint we want to implement.
We will just have a short taste of what web development with Odoo looks like. This topic is addressed in more depth in Chapter 13, Creating Website Frontend Features.


Web controllers are the components responsible for rendering web pages. Controllers are methods defined in an http.Controller class, and they are bound to URL endpoints. When that URL endpoint is accessed, the controller code executes, producing the HTML to be presented to the user. To help with rendering the HTML, we have the QWeb templating engine.
The convention is to place the code for controllers inside a /controllers subdirectory. First, edit library_app/__init__.py so that it also imports the controllers module directory:
from . import models
from . import controllers
We then need to add a library_app/controllers/__init__.py file so that the directory can be Python-imported, and add an import statement to it for the Python file we will add:
from . import main 
Now add the actual file for the controller, library_app/controllers/main.py, with the following code:
from odoo import http

class Books(http.Controller):

    @http.route('/library/books', auth='user')
    def list(self, **kwargs):
        Book = http.request.env['library.book']
        books = Book.search([])
        return http.request.render(
            'library_app.book_list_template', {'books': books})
The odoo.http module, imported here, is the core component providing web-related features. The http.Controller object is the class controller it should derive from. We use it for the main controller class.
The particular name we choose for the class and for their methods is not relevant. The @http.route decorator is the important part, since it declares the URL endpoint that will be bound to the class method, /books in our case. By default, access to URL endpoints requires the user to be logged in. It is good practice to explicitly refer to the route's authorization mode, so we added the auth='user' argument. We can allow for anonymous access by adding the auth='public' parameter to @http.route instead.

Note

If using auth='public', the code in the controller should use sudo() to elevate permissions before trying to search Books. This will be further discussed in Chapter 13 , Creating Website Frontend Features.
Inside the controller method, we access the environment using http.request.env. We use it to get a recordset with all active books in the catalogue.
The final step is to use http.request.render() to process the library_app.index_template QWeb template and generate the output HTML. We can make values available to the template through a dictionary, and this is used to pass the books recordset.
If we now restart the Odoo server, to reload the Python code, and try accessing the /library/books URL, we should get an error message in the server log: ValueError: External ID not found in the system: library_app.book_list_template. This is expected since we haven't defined that template yet. That should be our next step.
QWeb templates are a type of view, and should also go in the /views subdirectory. Let's create the views/book_list_template.xml file:
<?xml version="1.0" encoding="utf-8"?> 
<odoo>

<template id="book_list_template" name="Book List">
  <div id="wrap" class="container">
    <h1>Books</h1>
    <t t-foreach="books" t-as="book">
        <div class="row">
          <span t-field="book.name" />,
          <span t-field="book.date_published" />,
          <span t-field="book.publisher_id" />
        </div>
      </t>
  </div>
</template>

</odoo>
The <template> element is used to declare a QWeb template. In fact, it is a shortcut for an ir.ui.view record, and this is the base model where templates are stored. The template contains the HTML to use, and makes use of QWeb-specific attributes. t-foreach is used to loop through each item of the books variable, made available by the controller's http.request.render() call. t-field takes care of properly rendering the content of a record field.
This is just a glimpse of the QWeb syntax. More details can be found in Chapter 13, Creating Website Frontend Features.
We still need to declare this file in the module manifest, like the other XML data files, so that it gets loaded and can be made available. After doing this and performing a module upgrade, our web page should be working. Open the http://<my-server>:8069/library/books URL and you should see a simple list of the available Books.

Comments

Popular posts from this blog

The message and activity features

The message and activity features Odoo has available global  messaging  and activity planning features, provided by the  Discuss  application, with technical name mail. The mail module provides the  mail.thread  abstract class that makes it simple to add the messaging features to any model, and the  mail.activity.mixin  that adds planned activity features. This was done in  Chapter 4 ,  Extending Modules , to explain how to inherit features from mixin abstract classes. To add these features, we need to add the mail dependency to the add-on module,  library_checkout , and then have the library checkout model class inherit from the abstract classes providing the following features. Edit the  'depends'  key in the  library_checkout/__manifest__.py   file, to add the mail module, shown as follows: Copy 'depends': ['library_member' , 'mail' ], And edit the  library_checkout/m...

Setting up an nginx reverse proxy

Setting up an nginx reverse proxy While Odoo itself can serve web pages, it's strongly recommended that there is a  reverse  proxy positioned in front of it. A reverse proxy acts as an intermediary that manages the traffic between clients sending requests and the Odoo servers responding to them. Using a reverse proxy has several benefits. On the security side, it can do the following: Handle (and enforce) HTTPS protocols to encrypt traffic Hide the internal network characteristics Act as an application firewall, limiting the URLs accepted for processing Also, on the performance side, it can provide the following significant improvements: Cached static content, hence reducing the load on the Odoo servers Compressed content to speed up loading time Act as a load balancer, distributing load between several servers Apache is a popular choice when considering a reverse proxy, although  nginx  is a recent alternative with good technical argumen...

The QWeb template language

The QWeb template language The  QWeb  parser looks for special directives in the templates and replaces them with dynamically generated HTML. These directives are XML element attributes and can be used in any valid tag or element, such as  <div> ,  <span> , or  <field> . Sometimes, we may want to use a QWeb directive but we don't want to place it in any of the XML elements in our template. For those cases, we have a  <t>  special element that can have QWeb directives, such as  t-if  or  t-foreach , but is silent and won't have any output on the final XML/HTML produced. The QWeb directives will frequently make use of evaluated expressions to produce different results, depending on the current record values. There are two different QWeb implementations: client-side JavaScript and server-side Python. The reports and website pages use the server-side Python implementation of QWeb. Kanban views us...