Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions web_debranding/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
================
Web Debranding
================

This addon removes selected Odoo branding elements in the web backend.

- Removes the About block from General Settings.
- Blanks the default browser tab title fallback (no "Odoo").

Usage
-----

Install the module and open Settings to verify the About section is gone.
Open the web client and check the browser tab title no longer defaults to "Odoo".

Bug Tracker
-----------

If you encounter problems, please open an issue in the repository.

Credits
-------

Authors
~~~~~~~

- Odoo Community Association (OCA)

Maintainers
~~~~~~~~~~~

This module is part of the OCA/server-brand project.
2 changes: 2 additions & 0 deletions web_debranding/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright 2025 Milan Topuzov (https://milantopuzov.dev)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
18 changes: 18 additions & 0 deletions web_debranding/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2025 Milan Topuzov (https://milantopuzov.dev)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).
{
"name": "Web Debranding",
"summary": "Hide Odoo branding elements in web backend",
"version": "19.0.1.0.0",
"category": "Hidden",
"website": "https://github.com/OCA/server-brand",
"author": "Odoo Community Association (OCA)",
"license": "LGPL-3",
"depends": ["web", "base_setup"],
"data": [
"views/res_config_settings_debrand.xml",
"views/web_layout_debrand.xml",
],
"assets": {},
"installable": True,
}
3 changes: 3 additions & 0 deletions web_debranding/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
11 changes: 11 additions & 0 deletions web_debranding/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Tests package for web_debranding.

This package follows the same pattern as other modules in this repo,
importing local test modules so Odoo test discovery can load them.
"""

# Copyright 2025 Milan Topuzov (https://milantopuzov.dev)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).

from . import test_web_debranding
from . import test_title_debranding
57 changes: 57 additions & 0 deletions web_debranding/tests/test_title_debranding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2025 Milan Topuzov (https://milantopuzov.dev)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).

from lxml import html

from odoo import http
from odoo.tests import common


class _DummyRequest:
class _Session:
def __init__(self, debug=""):
self.debug = debug

def __init__(self, debug=""):
# Minimal session object with a 'debug' attribute
self.session = self._Session(debug=debug)

def csrf_token(self, _):
# Minimal CSRF call used by web.layout
return ""


class TestWebDebrandingTitle(common.TransactionCase):
def setUp(self):
super().setUp()
# Bind a dummy request into the http local stack so that the
# `odoo.http.request` LocalProxy resolves during QWeb evaluation.
self._dummy_request = _DummyRequest()
http._request_stack.push(self._dummy_request)
self.addCleanup(lambda: http._request_stack.pop())

def test_web_layout_title_no_fallback(self):
"""web.layout should not fallback to 'Odoo' when no title is provided.

Our view inherit replaces the <title> fallback with an empty string.
Validate that the rendered document title is empty and contains no 'Odoo'.
"""
content = self.env["ir.ui.view"]._render_template("web.layout", values={})
doc = html.fromstring(content)
titles = doc.xpath("//title")
self.assertTrue(titles, "Rendered web.layout should contain a <title> tag")
title_text = (titles[0].text or "").strip()
self.assertEqual(title_text, "")
self.assertNotIn("Odoo", title_text)

def test_web_layout_title_with_value(self):
"""When a title value is provided, it should be rendered as-is."""
expected = "My Custom Title"
content = self.env["ir.ui.view"]._render_template(
"web.layout", values={"title": expected}
)
doc = html.fromstring(content)
titles = doc.xpath("//title")
self.assertTrue(titles, "Rendered web.layout should contain a <title> tag")
title_text = (titles[0].text or "").strip()
self.assertEqual(title_text, expected)
22 changes: 22 additions & 0 deletions web_debranding/tests/test_web_debranding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2025 Milan Topuzov (https://milantopuzov.dev)
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).

from lxml import etree

from odoo.tests import common


class TestWebDebranding(common.TransactionCase):
def test_settings_about_section_hidden(self):
"""The About block in Settings form should be hidden."""
conf = self.env["res.config.settings"].create({})
view = conf.get_views([[False, "form"]])["views"]["form"]
doc = etree.XML(view["arch"])

about_nodes = doc.xpath("//div[@id='about']")
self.assertTrue(about_nodes, "About section container should exist in the view")
self.assertIn(
"invisible",
about_nodes[0].attrib,
"About section should be hidden via invisible='1'",
)
15 changes: 15 additions & 0 deletions web_debranding/views/res_config_settings_debrand.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Hide the About section in General Settings -->
<record id="view_res_config_settings_debrand_about" model="ir.ui.view">
<field name="name">res.config.settings.form.debrand.about</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="100" />
<field name="inherit_id" ref="base_setup.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[@id='about']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</field>
</record>
</odoo>
13 changes: 13 additions & 0 deletions web_debranding/views/web_layout_debrand.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- Remove default 'Odoo' fallback from page title -->
<template
id="web_layout_debrand_title"
inherit_id="web.layout"
name="Web layout debrand title"
>
<xpath expr="//title" position="attributes">
<attribute name="t-esc">title or ''</attribute>
</xpath>
</template>
</odoo>