Odoo 18 offers extensive customization options, allowing developers to tailor web pages to meet specific business needs. This guide explains how to modify web pages in Odoo 18, from basic model extensions to advanced controller customizations.
Odoo's modular design lets developers extend and modify core features without changing the base code, ensuring smooth upgrades and easy maintenance while offering flexibility to create personalized user experiences.
In this article, we’ll cover techniques for customizing Odoo 18 web pages, including model inheritance, view modifications, and controller overrides, along with best practices for efficient implementation.
Extending Odoo Models
Odoo uses a powerful inheritance mechanism that allows you to extend existing models without modifying the original code. This is achieved through Python classes that inherit from the base model.
Here's an example of how to extend the res.partner model to add a new field:
# -*- coding: utf-8 -*-
from odoo import models, fields
class ResPartner(models.Model):
_inherit = 'res.partner'
sale_count = fields.Integer(string='Sale_count', default=0, readonly=True)
In this example, we've added a sale_count field to the res.partner model. This new field can now be used in views and business logic related to partners.
Modifying Odoo Views
To modify an existing view, you create a new view definition that inherits from the original. Here's an example of how to add the sale_count field to the partner form view:
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_partner_form_inherit_blog" model="ir.ui.view">
<field name="name">res.partner.view.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='category_id']" position="after">
<field name="sale_count"/>
</xpath>
</field>
</record>
</odoo>
Extending Controllers
To extend a controller, create a new Python class that inherits from the original controller:
# -*- coding: utf-8 -*-
from odoo import http
from odoo.http import request
from odoo.addons.website.controllers.main import Home
class Website(Home):
@http.route('/', auth="public", website=True, sitemap=True)
def index(self, **kw):
partner_ids = request.env['res.partner'].sudo().search([])
for partner_id in partner_ids:
partner_id.sale_count = 0
orders = request.env['sale.order'].sudo().search([('state', 'in', ('sale', 'done'))])
for order in orders:
order.partner_id.sale_count = order.partner_id.sale_count + 1
super(Website, self).index()
website_partner_ids = request.env['res.partner'].sudo().search([('sale_count', '!=', 0)], order='sale_count desc', limit=4)
return request.render('website.homepage',{'website_partner_ids': website_partner_ids})
This example extends the homepage controller to include top customers in the context passed to the template.
Customizing Website Templates
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<template id="homepage_inherit_product_display"
inherit_id="website.homepage" name="Products" active="True">
<data inherit_id="website.homepage">
<xpath expr="//div[@id='wrap']" position="inside">
<input type="hidden" name="csrf_token"
t-att-value="request.csrf_token()"/>
<div class="container mt32 mb64">
<section>
<div class="product_details">
<center>
<h3>Top Customer</h3>
</center>
</div>
<br/>
<div class="oe_product_cart_new row"
style="overflow: hidden;">
<t t-foreach="website_partner_ids"
t-as="website_partner_id">
<div class="col-md-3 col-sm-3 col-xs-12"
style="padding:6px 6px 6px 6px;">
<form action="/shop/cart/update"
method="post"
class="card oe_product_cart"
data-publish="on">
<br/>
<center>
<div style="width:100%; height:155px;overflow: hidden;">
<img t-attf-src="/web/image?model=res.partner&field=image_1920&id=#{website_partner_id.id}"
class="img img-fluid"
style="padding: 0px; margin: 0px; width:auto; height:100%;"/>
</div>
</center>
<br/>
<div class="card-body p-0 text-center o_wsale_product_information">
<div class="p-2 o_wsale_product_information_text">
<h6 class="o_wsale_products_item_title">
<t t-esc="website_partner_id.name"/>
</h6>
</div>
<div class="o_wsale_product_btn"
data-oe-model="ir.ui.view"
data-oe-id="1561"
data-oe-field="arch"
data-oe-xpath="/t[1]/form[1]/div[2]/div[2]"/>
</div>
<span class="o_ribbon " style=""/>
</form>
</div>
</t>
</div>
</section>
</div>
</xpath>
</data>
</template>
</odoo>
This template extends the homepage with a visually engaging "Top Customer" section. By inheriting from the existing website.homepage template, it allows additional content to be seamlessly integrated within the main wrapper div. This added section features a centered "Top Customer" heading, followed by a grid layout that dynamically displays customer cards for each partner in website_partner_ids. Each card presents a partner’s image, loaded from the res.partner model, and their name, making the information visually accessible and engaging for website visitors.
Modifying web pages in Odoo 18 offers extensive possibilities for enhancing and personalizing your business's online presence. This guide explores a range of techniques—from basic front-end editing to advanced backend customizations—that enable you to create unique and impactful web experiences.
To read more about How to Modify Existing Web Pages in Odoo 17, refer to our blog How to Modify Existing Web Pages in Odoo 17.