Enable Dark Mode!
how-to-customize-odoo-erp-14-website-templates.jpg
By: Cirin C Baby

How to Customize Odoo 14 Website Templates?

Technical Odoo 14 Website&E-commerce

In this blog, we are going to discuss how to customize the templates on the Odoo website and add a search option to a page. So the main step in customizing a web page is inheriting its template. After inheriting, if you want to remove something from the existing template just remove the lines of code, or if you want to add something you can use xpath to determine where to add the new elements in that template.

So in this example, I am using the portal to customize. let me take the sale order page

odoo-can-empower-your-small-scale-business-cybrosys

From the figure, we can see that the table header columns contain only sale order, order date, and total. So here I am going to add the partner name of the related sale order.so we can do this by 

1. Inheriting the template 

2. Overriding the template

1) Inheriting the template

In the module, inside views create an xml file and inherit the template as follows 

	<odoo>
   <data>
       <template id="portal_my_orders_inherit" name="My Sales Orders Inherit" inherit_id="sale.portal_my_orders" >
           <xpath expr="//tr[hasclass('active')]" position="replace">
               <th>
                   <span class='d-none d-md-inline'>Sales Order #</span>
                   <span class='d-block d-md-none'>Ref.</span>
               </th>
               <th class="text-right">Order Date</th>
               <th class="text-right">Partner</th>
               <th class="text-center"/>
               <th class="text-right">Total</th>
           </xpath>
           <xpath expr="//td[hasclass('text-center')]" position="before">
               <td class="text-right"><span t-field="order.partner_id.name"/></td>
           </xpath>
   </template>
   </data>
</odoo>

So from the above code ,it inherits the template portal_my_orders of sale module and is using xpath to go to a certain position.So after this, update the app list and install the module, then we will get as

odoo-can-empower-your-small-scale-business-cybrosys

So from the above image, we can see a new column named Partner has appeared.

2) Override the template

So Instead of using the above method, we can override the template as below.

<template id="sale.portal_my_orders" name="My Sales Orders">
   <t t-call="portal.portal_layout">
       <t t-set="breadcrumbs_searchbar" t-value="True"/>
       <t t-call="portal.portal_searchbar">
           <t t-set="title">Sales Orders</t>
       </t>
       <t t-if="not orders">
           <p>There are currently no orders for your account.</p>
       </t>
       <t t-if="orders" t-call="portal.portal_table">
           <thead>
               <tr class="active">
                   <th>
                       <span class='d-none d-md-inline'>Sales Order #</span>
                       <span class='d-block d-md-none'>Ref.</span>
                   </th>
                   <th class="text-right">Partner</th>
                   <th class="text-right">Order Date</th>
                   <th class="text-center"/>
                   <th class="text-right">Total</th>
               </tr>
           </thead>
           <t t-foreach="orders" t-as="order">
               <tr>
                   <td><a t-att-href="order.get_portal_url()"><t t-esc="order.name"/></a></td>
                   <td class="text-right"><span t-field="order.partner_id.name"/></td>
                   <td class="text-right">
                       <span t-field="order.date_order" t-options="{'widget': 'date'}"/>&amp;nbsp;
                       <span class='d-none d-md-inline' t-field="order.date_order" t-options="{'time_only': True}"/>
                   </td>
                   <td class="text-center">
                       <span t-if="order.state == 'done'"  class="badge badge-pill badge-success">
                           <i class="fa fa-fw fa-check" role="img" aria-label="Done" title="Done"/>Done
                       </span>
                   </td>
                   <td class="text-right"><span t-field="order.amount_total"/></td>
               </tr>
           </t>
       </t>
   </t>
</template>

If we look at the first line, the template is overridden as the module name.template_id.So here all lines of templates are copied here and updating is done accordingly(highlighted lines)

After installing the module we can see as

odoo-can-empower-your-small-scale-business-cybrosys

How to add a search bar option in the website template?

Let's see how we can add search options(search bar) to this template.

If we look at the second t-call of the template,we can see it's calling another template(portal.portal_searchbar).So the only thing we need to do is to override the controller that calls this template.

from odoo import fields, http, _
from odoo.http import request
from odoo.addons.sale.controllers.portal import CustomerPortal
from odoo.addons.portal.controllers.portal import pager as portal_pager, get_records_pager
from odoo.osv.expression import OR
class CustomerPortal(CustomerPortal):
   @http.route(['/my/orders', '/my/orders/page/<int:page>'], type='http', auth="user", website=True)
   def portal_my_orders(self, page=1, date_begin=None, search=None, search_in='content', date_end=None, sortby=None, **kw):
       values = self._prepare_portal_layout_values()
       partner = request.env.user.partner_id
       SaleOrder = request.env['sale.order']
       domain = [
           ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]),
           ('state', 'in', ['sale', 'done'])
       ]
       searchbar_inputs = {
           'order': {'input': 'name', 'label': _('Search in Order')},
           'all': {'input': 'all', 'label': _('Search in All')},
       }
       if search and search_in:
           search_domain = []
           if search_in in ('name', 'all'):
               search_domain = OR([search_domain, [('name', 'ilike', search)]])
           domain += search_domain
       searchbar_sortings = {
           'date': {'label': _('Order Date'), 'order': 'date_order desc'},
           'name': {'label': _('Reference'), 'order': 'name'},
           'stage': {'label': _('Stage'), 'order': 'state'},
       }
       # default sortby order
       if not sortby:
           sortby = 'date'
       sort_order = searchbar_sortings[sortby]['order']
       if date_begin and date_end:
           domain += [('create_date', '>', date_begin), ('create_date', '<=', date_end)]
       # count for pager
       order_count = SaleOrder.search_count(domain)
       # pager
       pager = portal_pager(
           url="/my/orders",
           url_args={'date_begin': date_begin, 'date_end': date_end, 'sortby': sortby},
           total=order_count,
           page=page,
           step=self._items_per_page
       )
       # content according to pager
       orders = SaleOrder.search(domain, order=sort_order, limit=self._items_per_page, offset=pager['offset'])
       request.session['my_orders_history'] = orders.ids[:100]
       values.update({
           'date': date_begin,
           'orders': orders.sudo(),
           'search': search,
           'searchbar_inputs': searchbar_inputs,
           'search_in': search_in,
           'page_name': 'order',
           'pager': pager,
           'default_url': '/my/orders',
           'searchbar_sortings': searchbar_sortings,
           'sortby': sortby,
       })
       return request.render("sale.portal_my_orders", values)

In the code , searchbar_inputs is an filter or domain in which area/condition the search should do.Here the  lines,

searchbar_inputs = {
           'order': {'input': 'name', 'label': _('Search in Order')},
           'all': {'input': 'all', 'label': _('Search in All')},
       }

defines the search filter option,ie just a name for filter.the changes can be seen as

odoo-can-empower-your-small-scale-business-cybrosys

Ie, on clicking the dropdown option on the search bar we can select the condition, and after that, we type the text for search .so the lines,

if search and search_in:
           search_domain = []
           if search_in in ('name', 'all'):
               search_domain = OR([search_domain, [('name', 'ilike', search)]])
           domain += search_domain

Here the search means the text we type in the search bar and the search_in means the search filter condition or searchbar_inputs selected. so here we are adding the domain to search and after its append to the main domain, and finally, on searching the text on the search bar, the domain is added and will get the result as below.

odoo-can-empower-your-small-scale-business-cybrosys


So in this ways, we can customize the templates on the website



If you need any assistance in odoo, we are online, please chat with us.



1
Comments

flowgiri

Great guide! I found customizing Odoo 14 website templates much easier now. Thanks for the step-by-step walkthrough!

20/08/2023

-

10:26AM



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message