Skip to content
Merged
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
100 changes: 100 additions & 0 deletions web_theme_color/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
===============
Web Theme Color
===============

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f7a4de7e94ea4f2272deb4559029be1c6453a345544d6c79412c0f1512076584
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-Escodoo%2Fserver--addons-lightgray.png?logo=github
:target: https://github.com/Escodoo/server-addons/tree/18.0/web_theme_color
:alt: Escodoo/server-addons

|badge1| |badge2| |badge3|

Set the Odoo backend brand color from a system parameter, without
writing a module for each customer.

The navbar, its bottom border and the primary buttons follow the color.
Link and focus colors keep the standard Odoo action teal.

The color is a scss variable, not a runtime style, so changing the
parameter rewrites the theme scss file and rebuilds the web assets. The
change is global for the database: every company and every user sees the
same color.

A few spots keep the Odoo purple because the core hardcodes it instead
of reading the variable: the table picker of the html editor and the
``theme-color`` meta tag, which colors the browser bar on mobile.
Document layout colors (PDF and email) and the Website theme palette are
separate settings.

**Table of contents**

.. contents::
:local:

Usage
=====

Go to **Settings > Technical > Parameters > System Parameters** and
change the value of these two parameters, created by the module:

- ``web_theme_color.primary`` (default ``#71639e``): brand color of the
backend.
- ``web_theme_color.primary_dark`` (default ``#71639e``): brand color
in Enterprise dark mode.

The value is a hexadecimal color such as ``#D01000``. Both the three
digit (``#D10``) and the six digit form are accepted. Any other value is
rejected when you save the parameter, so a typo cannot break the assets.

``web_theme_color.primary_dark`` only has an effect on Odoo Enterprise,
which is where dark mode exists. On Community it can be left at the
default.

After saving, reload the backend with a hard refresh (Ctrl+F5) so the
browser drops the cached assets. The default values are the standard
Odoo colors, so installing the module alone changes nothing.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/Escodoo/server-addons/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/Escodoo/server-addons/issues/new?body=module:%20web_theme_color%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Escodoo

Contributors
------------

- ``Escodoo <https://www.escodoo.com.br>``\ \_:

- Wesley Oliveira wesley.oliveira@escodoo.com.br

Maintainers
-----------

This module is part of the `Escodoo/server-addons <https://github.com/Escodoo/server-addons/tree/18.0/web_theme_color>`_ project on GitHub.

You are welcome to contribute.
1 change: 1 addition & 0 deletions web_theme_color/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
34 changes: 34 additions & 0 deletions web_theme_color/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2026 - TODAY, Escodoo
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Web Theme Color",
"summary": """
Set the backend brand color from a system parameter""",
"version": "18.0.1.0.0",
"license": "AGPL-3",
"author": "Escodoo",
"website": "https://github.com/Escodoo/server-addons",
"depends": [
"web",
"web_editor",
],
"data": [
"data/ir_config_parameter.xml",
],
"assets": {
"web._assets_primary_variables": [
(
"prepend",
"web_theme_color/static/src/scss/primary_variables.scss",
),
],
"web.dark_mode_variables": [
(
"prepend",
"web_theme_color/static/src/scss/primary_variables.dark.scss",
),
],
},
"installable": True,
}
14 changes: 14 additions & 0 deletions web_theme_color/data/ir_config_parameter.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2026 - TODAY, Escodoo
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo noupdate="1">
<record id="param_web_theme_color_primary" model="ir.config_parameter">
<field name="key">web_theme_color.primary</field>
<field name="value">#71639e</field>
</record>

<record id="param_web_theme_color_primary_dark" model="ir.config_parameter">
<field name="key">web_theme_color.primary_dark</field>
<field name="value">#71639e</field>
</record>
</odoo>
2 changes: 2 additions & 0 deletions web_theme_color/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import web_theme_color
from . import ir_config_parameter
32 changes: 32 additions & 0 deletions web_theme_color/models/ir_config_parameter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2026 - TODAY, Escodoo
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import api, models

from .web_theme_color import THEME_PARAMS


class IrConfigParameter(models.Model):
_inherit = "ir.config_parameter"

def _apply_web_theme_color(self, keys):
if THEME_PARAMS.intersection(keys):
self.env["web.theme.color"]._apply_colors()

@api.model_create_multi
def create(self, vals_list):
records = super().create(vals_list)
records._apply_web_theme_color(records.mapped("key"))
return records

def write(self, vals):
old_keys = set(self.mapped("key"))
res = super().write(vals)
self._apply_web_theme_color(old_keys | set(self.mapped("key")))
return res

def unlink(self):
keys = self.mapped("key")
res = super().unlink()
self._apply_web_theme_color(keys)
return res
80 changes: 80 additions & 0 deletions web_theme_color/models/web_theme_color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Copyright 2026 - TODAY, Escodoo
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

import re

from odoo import api, models
from odoo.exceptions import ValidationError

PARAM_PRIMARY = "web_theme_color.primary"
PARAM_PRIMARY_DARK = "web_theme_color.primary_dark"

DEFAULT_PRIMARY = "#71639e"
DEFAULT_PRIMARY_DARK = "#71639e"

COLOR_PATTERN = re.compile(r"^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$")

# (parameter, default, asset to rewrite, bundle it belongs to)
THEME_ASSETS = (
(
PARAM_PRIMARY,
DEFAULT_PRIMARY,
"/web_theme_color/static/src/scss/primary_variables.scss",
"web._assets_primary_variables",
),
(
PARAM_PRIMARY_DARK,
DEFAULT_PRIMARY_DARK,
"/web_theme_color/static/src/scss/primary_variables.dark.scss",
"web.dark_mode_variables",
),
)

THEME_PARAMS = frozenset(asset[0] for asset in THEME_ASSETS)

SCSS_TEMPLATE = """\
// Generated from the system parameter %(param)s.
// Change that parameter instead of editing this file.
$o-community-color: %(color)s !default;
$o-enterprise-color: %(color)s !default;
$o-brand-odoo: %(color)s !default;
$o-brand-primary: %(color)s !default;
"""


class WebThemeColor(models.AbstractModel):
_name = "web.theme.color"
_description = "Backend Theme Color"

@api.model
def _check_color(self, param, color):
if not COLOR_PATTERN.match(color or ""):
raise ValidationError(
self.env._(
"%(color)s is not a valid color for %(param)s.\n\n"
"Use a hexadecimal value such as #D01000.",
color=color or "",
param=param,
)
)
return color

@api.model
def _apply_colors(self):
"""Rewrite the theme scss files from the system parameters.

The colors are scss variables, so they are only picked up when the
bundle is compiled. Saving the asset replaces the file and invalidates
Comment thread
WesleyOliveira98 marked this conversation as resolved.
Resolved
the bundle; on the default color the customization is removed instead,
so no attachment is left behind.
"""
assets = self.env["web_editor.assets"].sudo()
params = self.env["ir.config_parameter"].sudo()
for param, default, url, bundle in THEME_ASSETS:
color = params.get_param(param) or default
self._check_color(param, color)
if color.lower() == default.lower():
assets.reset_asset(url, bundle)
continue
content = SCSS_TEMPLATE % {"color": color, "param": param}
assets.save_asset(url, bundle, content, "scss")
3 changes: 3 additions & 0 deletions web_theme_color/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
3 changes: 3 additions & 0 deletions web_theme_color/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `Escodoo <https://www.escodoo.com.br>`_:

* Wesley Oliveira <wesley.oliveira@escodoo.com.br>
15 changes: 15 additions & 0 deletions web_theme_color/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Set the Odoo backend brand color from a system parameter, without writing a
module for each customer.

The navbar, its bottom border and the primary buttons follow the color. Link
and focus colors keep the standard Odoo action teal.

The color is a scss variable, not a runtime style, so changing the parameter
rewrites the theme scss file and rebuilds the web assets. The change is global
for the database: every company and every user sees the same color.

A few spots keep the Odoo purple because the core hardcodes it instead of
reading the variable: the table picker of the html editor and the
`theme-color` meta tag, which colors the browser bar on mobile. Document
layout colors (PDF and email) and the Website theme palette are separate
settings.
17 changes: 17 additions & 0 deletions web_theme_color/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Go to **Settings > Technical > Parameters > System Parameters** and change the
value of these two parameters, created by the module:

- `web_theme_color.primary` (default `#71639e`): brand color of the backend.
- `web_theme_color.primary_dark` (default `#71639e`): brand color in Enterprise
dark mode.

The value is a hexadecimal color such as `#D01000`. Both the three digit
(`#D10`) and the six digit form are accepted. Any other value is rejected when
you save the parameter, so a typo cannot break the assets.

`web_theme_color.primary_dark` only has an effect on Odoo Enterprise, which is
where dark mode exists. On Community it can be left at the default.

After saving, reload the backend with a hard refresh (Ctrl+F5) so the browser
drops the cached assets. The default values are the standard Odoo colors, so
installing the module alone changes nothing.
Binary file added web_theme_color/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading