OWL ‐ Client Actions - vec-ltd/odoo-docs GitHub Wiki
Actions in Odoo cover a lot of different things. Lots of things are considered to be 'actions'. For example, viewing model data from the database is a 'Window Action'.
Window Actions can be customised by using different 'Views'. For example, tree and form views allow you to view a list of models, or view a single model or create and edit an exiting model.
You can have a 'Cron Action' which will cause something to run at regular intervals. There are a myriad of different actions, but there is one in particular that is useful for Odoo developers, and that is the 'Client Action'.
Now I have a feeling that Client Actions can be used more widely than just this particular purpose, but one thing they can definitely be used for is to build completely custom UI pages inside Odoo.
Since Menu items can be attached to an action (usually a Window Action), being able to attach a Menu item to a Client Action opens the door to being able to click on a menu and be routed to a custom page.
So if your menu links to an 'ir.actions.act_window' then clicking the menu will open a Window Action. If the menu links to 'ir.actions.client' then it will open a Client Action.
By linking the Client Action to an OWL Component, we can then get full control of what gets rendered on the screen when the user clicks that menu button.
So putting this into code, we need something like the following:
<menuitem name="Custom Page" id="my_module.menu_custom_page" parent="my_module.menu_root"
sequence="4"
action="my_module.custom_page_action"/>
<record model="ir.actions.client" id="my_module.custom_page_action">
<field name="name">Custom Page Title</field>
<field name="tag">my_module.custom_page_tag</field>
</record>
Notice how the action attribute in the menuitem is linked to the id attribute of the record.
Then in JS we can define a plain old OWL component like this:
/** @odoo-module **/
import { registry } from "@web/core/registry";
const { Component, useState } = owl;
class CustomPageComponent extends Component {
static template = "my_module.custom_page_template";
}
registry.category("actions").add("my_module.custom_page_tag", CustomPageComponent);
That last line is key, notice how we are linking the tag back to the tag field in the ?
If all these things are linked correctly, then when you click that menu button, it will open the client action, and that will then pull the OWL component out of the actions registry and mount it inside the application.
You can then define an XML template to store the actual HTML:
<?xml version="1.0" encoding="utf-8"?>
<templates xml:space="preserve">
<t t-name="my_module.custom_page_template" owl="1">
<h1>HTML Goes HERE</h1>
</t>
</templates>
So as long as t-name matches the static template attribute in the JS class, then everything should be linked up correctly and should render on the screen.
You do have to ensure that your JS files are in the correct location, and that they are configured in the correct asset bundle in the module manifest file.
This, in a nutshell, is how you can break away from the confines of the 'Window Action', which requires a specific 'View Type' to be selected (tree, form, kanban etc.), and just build regular old HTML pages.
You can essentially embed an entire OWL application inside the main window of the Odoo Web Client.