To create a new Odoo module with different menus containing iframes, follow these steps. Additionally, we'll address how to maintain the iframe state during module switches.
1. Module Creation Basics
a. Folder Structure
Create the following directory structure for your custom module:
custom_module/
├── __init__.py
├── __manifest__.py
├── models/
│ ├── __init__.py
├── views/
│ ├── custom_module_views.xml
│ ├── custom_module_menus.xml
2. Define __manifest__.py
This file specifies the metadata for your module:
{
'name': 'Custom Iframe Module',
'version': '16.0.1.0',
'summary': 'A module to add menus with iframes',
'description': 'This module adds menus that display specific iframes.',
'author': 'Your Name',
'website': 'https://yourwebsite.com',
'category': 'Custom',
'depends': ['base'],
'data': [
'views/custom_module_menus.xml',
'views/custom_module_views.xml',
],
'installable': True,
'application': True,
'license': 'LGPL-3',
}
3. Add Menus in custom_module_menus.xml
Define menus and link them to actions for the iframe views:
<odoo>
<menuitem id="menu_custom_module" name="Custom Module" sequence="10" />
<menuitem id="menu_iframe_1" name="Iframe 1" parent="menu_custom_module" action="action_iframe_1" sequence="20" />
<menuitem id="menu_iframe_2" name="Iframe 2" parent="menu_custom_module" action="action_iframe_2" sequence="30" />
</odoo>
4. Define Views with Iframes in custom_module_views.xml
Here’s an example of how to embed iframes:
<odoo>
<!-- Action for Iframe 1 -->
<record id="action_iframe_1" model="ir.actions.act_window">
<field name="name">Iframe 1</field>
<field name="res_model">custom.module.iframe</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="context">{'iframe_url': 'https://example.com/page1'}</field>
</record>
<!-- Action for Iframe 2 -->
<record id="action_iframe_2" model="ir.actions.act_window">
<field name="name">Iframe 2</field>
<field name="res_model">custom.module.iframe</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="context">{'iframe_url': 'https://example.com/page2'}</field>
</record>
<!-- Form View to Display the Iframe -->
<record id="view_custom_module_form" model="ir.ui.view">
<field name="name">custom.module.form</field>
<field name="model">custom.module.iframe</field>
<field name="arch" type="xml">
<form>
<sheet>
<iframe style="width: 100%; height: 800px;" src="javascript:void(0);" t-att-src="context.get('iframe_url')"/>
</sheet>
</form>
</field>
</record>
</odoo>
5. Define the Model in models/__init__.py
For a simple iframe display, you don’t need a complex model, but you can define a dummy model:
from . import models
6. Handle State Persistence
By default, the iframe will refresh when navigating back to its menu. To preserve its state:
- Use Local Storage in JavaScript:
Extend the web client to save and restore the iframe state.
Create a file static/src/js/custom_iframe.js:odoo.define('custom_module.iframe_state', function (require) {
"use strict";
const AbstractAction = require('web.AbstractAction');
const CustomIframe = AbstractAction.extend({
start: function () {
const iframeElement = this.$('iframe');
const urlKey = this.context.iframe_url;
// Restore saved state
const savedState = localStorage.getItem(urlKey);
if (savedState) {
iframeElement.attr('src', savedState);
}
// Save state on navigation
iframeElement.on('load', function () {
localStorage.setItem(urlKey, iframeElement.attr('src'));
});
return this._super.apply(this, arguments);
}
});
return CustomIframe;
});
- Include the Script in the Manifest:
Add this JavaScript file to the module’s assets:
'assets': {
'web.assets_backend': [
'custom_module/static/src/js/custom_iframe.js',
],
},
7. Restart and Install the Module
- Restart your Odoo server:
sudo service odoo restart
- Go to Apps, update the app list, and install the module.
8. Test and Debug
- Navigate to the custom menus and confirm the iframes display the correct content.
- Switch between modules and ensure the iframe remembers its state.
With this implementation, you have a scalable and stateful iframe module in Odoo 16.