主题设置¶
在您的开发环境完全配置好之后,您可以开始构建主题模块的骨架。在本章中,您将了解到如何:
启用/禁用网站构建器的默认选项和模板。
定义设计中使用的颜色和字体。
充分利用 Bootstrap 变量。
添加自定义样式和 JavaScript。
主题模块¶
Odoo 自带一个默认主题,提供基本的结构和布局。当你创建一个新的主题时,你是在扩展默认主题。
记得在开发环境中运行 Odoo 时,将包含你模块的目录添加到 addons-path
命令行参数中。
技术命名¶
第一步是创建一个新的目录。
website_airproof
文件结构¶
主题像任何 Odoo 模块一样进行打包。即使你正在设计一个基本的网站,也需要将它的主题打包成一个模块。
website_airproof
├── data
├── i18n
├── lib
├── static
│ ├── description
│ ├── fonts
│ ├── image_shapes // Shapes for images
│ ├── shapes // Shapes for background
│ └── src
│ ├── img
│ │ ├── content // For those used in the pages of your website
│ │ └── wbuilder // For those used in the builder
│ ├── js
│ ├── scss
│ └── snippets // custom snippets
├── views
├── __init__.py
└── __manifest__.py
文件夹 |
描述 |
---|---|
数据 |
预设、菜单、页面、图片、形状、… ( |
国际化(i18n) |
翻译文件( |
lib |
外部库 ( |
静态 |
自定义资源( |
视图 |
自定义视图和模板 ( |
初始化¶
一个 Odoo 模块也是一个包含 __init__.py
文件的 Python 包,该文件包含模块中各种 Python 文件的导入指令。目前,此文件可以保持为空。
声明¶
一个 Odoo 模块通过其清单文件进行声明。该文件将一个 Python 包声明为 Odoo 模块,并指定模块的元数据。它至少必须包含 name
字段,该字段是必填项。通常,它还包含更多相关信息。
/website_airproof/__manifest__.py
¶{
'name': 'Airproof Theme',
'description': '...',
'category': 'Website/Theme',
'version': '15.0.0',
'author': '...',
'license': '...',
'depends': ['website'],
'data': [
# ...
],
'assets': {
# ...
},
}
字段 |
描述 |
---|---|
名称 |
模块的可读名称(必填) |
描述 |
模块的扩展描述,使用 reStructuredText 格式 |
类别 |
Odoo 中的分类类别 |
版本 |
Odoo 版本:此模块所针对的版本 |
作者 |
模块作者名称 |
许可证 |
模块的分发许可 |
依赖项 |
Odoo 模块必须在本模块之前加载,要么是因为本模块使用了它们创建的功能,要么是因为它修改了它们定义的资源。 |
数据 |
XML 文件列表 |
资源 |
SCSS 和 JS 文件列表 |
注解
要创建一个网站主题,您只需安装“网站”应用。如果您需要其他应用(博客、活动、电子商务等),也可以一并添加。
默认选项¶
首先,尝试通过使用 Odoo 的默认选项来构建你的主题。这可以确保两件事:
你不需要重新发明已经存在的东西。例如,由于 Odoo 提供了在页脚添加边框的选项,你不应该自己重新编写它。相反,首先启用默认选项,如果需要的话,再对其进行扩展。
用户仍然可以使用您主题下的所有 Odoo 功能。例如,如果您重新定义了页脚的边框,可能会破坏默认选项或使其无用,从而给用户带来不好的体验。此外,您的重新实现可能不如默认选项效果好,因为其他 Odoo 功能可能依赖于它。
小技巧
每级缩进使用四个空格。
不要使用制表符。
永远不要混合使用空格和制表符。
另请参见
Odoo 变量¶
Odoo 声明了许多 CSS 规则,大多数都可以通过覆盖相关的 SCSS 变量来进行完全自定义。为此,创建一个 primary_variables.scss
文件,并将其添加到 _assets_primary_variables
资源包中。
声明
/website_airproof/__manifest__.py
¶'assets': {
'web._assets_primary_variables': [
('prepend', 'website_airproof/static/src/scss/primary_variables.scss'),
],
},
通过阅读源代码,与选项相关的变量很容易被注意到。
<we-button title="..."
data-name="..."
data-customize-website-views="..."
data-customize-website-variable="'Sidebar'"
data-img="..."/>
这些变量可以通过 $o-website-value-palettes
映射进行重写,例如。
全局¶
声明
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
// Templates
// Colors
// Fonts
// Buttons
// ...
),
);
小技巧
该文件只能包含 SCSS 变量和混入的定义和覆盖。
另请参见
字体¶
你可以在网站上嵌入任何字体。网站构建器会自动将其添加到字体选择器中。
声明
/website_airproof/static/src/scss/primary_variables.scss
¶$o-theme-font-configs: (
<font-name>: (
'family': <css font family list>,
'url' (optional): <related part of Google fonts URL>,
'properties' (optional): (
<font-alias>: (
<website-value-key>: <value>,
...,
),
...,
)
)
使用
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
'font': '<font-name>',
'headings-font': '<font-name>',
'navbar-font': '<font-name>',
'buttons-font': '<font-name>',
),
);
谷歌字体¶
/website_airproof/static/src/scss/primary_variables.scss
¶$o-theme-font-configs: (
'Poppins': (
'family': ('Poppins', sans-serif),
'url': 'Poppins:400,500',
'properties' : (
'base': (
'font-size-base': 1rem,
),
),
),
);
自定义字体¶
首先,创建一个特定的 SCSS 文件来声明您的自定义字体。
/website_airproof/__manifest__.py
¶'assets': {
'web.assets_frontend': [
'website_airproof/static/src/scss/font.scss',
],
},
然后,使用 @font-face
规则,以允许将您自定义的字体加载到您的网站上。
/website_airproof/static/src/scss/font.scss
¶@font-face {
font-family: '<font-name>';
...
}
/website_airproof/static/src/scss/primary_variables.scss
¶$o-theme-font-configs: (
'Proxima Nova': (
'family': ('Proxima Nova', sans-serif),
'properties' : (
'base': (
'font-size-base': 1rem,
),
),
),
);
小技巧
建议为您的字体使用 .woff 格式。
颜色¶
网站构建器依赖于由五种命名颜色组成的调色板。在您的主题中定义这些颜色可以确保风格的一致性。
颜色 |
描述 |
---|---|
o-color-1 |
主要的 |
o-color-2 |
次要的 |
o-color-3 |
额外 |
o-color-4 |
白色 |
o-color-5 |
黑色的 |

声明
/website_airproof/static/src/scss/primary_variables.scss
¶$o-color-palettes: map-merge($o-color-palettes,
(
'airproof': (
'o-color-1': #bedb39,
'o-color-2': #2c3e50,
'o-color-3': #f2f2f2,
'o-color-4': #ffffff,
'o-color-5': #000000,
),
)
);
将创建的调色板添加到网站构建器提供的调色板列表中。
$o-selected-color-palettes-names: append($o-selected-color-palettes-names, 'airproof');
使用
/website_airproof/static/src/scss/primary_variables.scss
¶$o-website-values-palettes: (
(
'color-palettes-name': 'airproof',
),
);

颜色组合
基于之前定义的五种颜色调色板,网站构建器会自动生成五种颜色组合,每种组合定义了背景色、文字颜色、标题颜色、链接颜色、主要按钮颜色和次要按钮颜色。这些颜色之后可以由用户进行自定义。

在颜色组合中使用的颜色是可访问的,并可以通过使用特定前缀(o-cc
用于 color combination
)的 BS $colors
地图进行重写。
/website_airproof/static/src/scss/primary_variables.scss
¶$o-color-palettes: map-merge($o-color-palettes,
(
'airproof': (
'o-cc*-bg': 'o-color-*',
'o-cc*-text': 'o-color-*',
'o-cc*-headings': 'o-color-*',
'o-cc*-h2': 'o-color-*',
'o-cc*-h3': 'o-color-*',
'o-cc*-h4': 'o-color-*',
'o-cc*-h5': 'o-color-*',
'o-cc*-h6': 'o-color-*',
'o-cc*-link': 'o-color-*',
'o-cc*-btn-primary': 'o-color-*',
'o-cc*-btn-primary-border': 'o-color-*',
'o-cc*-btn-secondary': 'o-color-*',
'o-cc*-btn-secondary-border': 'o-color-*',
),
)
);
注解
对于每个 o-cc*
,将 *
替换为对应的数字(1 - 5),以选择所需的颜色组合。
默认文字颜色是 o-color-5
。如果背景太暗,它会自动切换为 o-color-4
颜色。
另请参见
演示页面
网站构建器会自动生成一个页面,用于查看主题配色方案的颜色组合:http://localhost:8069/website/demo/color-combinations
引导程序变量¶
Odoo 默认集成了 Bootstrap。您可以使用该框架的所有变量和混入(mixins)。
如果 Odoo 没有提供您需要的变量,可能存在一个 Bootstrap 变量可以实现您的需求。实际上,所有 Odoo 布局都遵循 Bootstrap 结构,并使用 Bootstrap 组件或其扩展。如果您自定义了一个 Bootstrap 变量,将会为整个用户网站添加一种通用样式。
使用一个专门添加到 _assets_frontend_helpers
套件的文件来覆盖 Bootstrap 的值,而不是修改 primary_variables.scss
文件。
声明
/website_airproof/__manifest__.py
¶'assets': {
'web._assets_frontend_helpers': [
('prepend', 'website_airproof/static/src/scss/bootstrap_overridden.scss'),
],
},
使用
/website_airproof/static/src/scss/bootstrap_overridden.scss
¶// Typography
$h1-font-size: 4rem !default;
// Navbar
$navbar-nav-link-padding-x: 1rem!default;
// Buttons + Forms
$input-placeholder-color: o-color('o-color-1') !default;
// Cards
$card-border-width: 0 !default;
小技巧
该文件只能包含 SCSS 变量和混入的定义和覆盖。
警告
不要覆盖那些依赖于 Odoo 变量的 Bootstrap 变量。否则,可能会破坏用户通过网站构建器自定义它们的可能性。
演示页面
http://localhost:8069/网站/演示/bootstrap
视图¶
对于某些选项,除了网站构建器变量外,您还需要激活一个特定的视图。
通过阅读源代码,可以轻松找到与选项相关的模板。
<we-button title="..."
data-name="..."
data-customize-website-views="website.template_header_default"
data-customize-website-variable="'...'"
data-img="..."/>
<template id="..." inherit_id="..." name="..." active="True"/>
<template id="..." inherit_id="..." name="..." active="False"/>
Example
更改菜单项的水平对齐方式
/网站防尘/数据/预设.xml
¶<record id="website.template_header_default_align_center" model="ir.ui.view">
<field name="active" eval="True"/>
</record>
同样的逻辑也可以用于其他 Odoo 应用程序。
电子商务 - 显示产品分类
<record id="website_sale.products_categories" model="ir.ui.view">
<field name="active" eval="False"/>
</record>
门户 - 禁用语言选择器
<record id="portal.footer_language_selector" model="ir.ui.view">
<field name="active" eval="False"/>
</record>
资产¶
对于这一部分,我们将参考 assets_frontend
资产包,该包位于 web 模块中。此资产包指定了由网站构建器加载的资产列表,我们的目标是将您的 SCSS 和 JS 文件添加到该资产包中。
样式¶
网站构建器结合 Bootstrap 非常适合定义网站的基本样式。但要设计出独特的内容,你应该更进一步。为此,你可以轻松地将任何 SCSS 文件添加到你的主题中。
声明
/website_airproof/__manifest__.py
¶'assets': {
'web.assets_frontend': [
'website_airproof/static/src/scss/theme.scss',
],
},
你可以自由复用来自你的 Bootstrap 文件以及 Odoo 在 theme.scss
文件中使用的变量。
Example
/website_airproof/static/src/scss/主题.scss
¶ blockquote {
border-radius: $rounded-pill;
color: o-color('o-color-3');
font-family: o-website-value('headings-font');
}
交互性¶
Odoo 支持三种不同类型的 JavaScript 文件:
:ref:`普通 JavaScript 文件 <frontend/modules/plain_js>`(无模块系统),
:ref:`Odoo 模块 <frontend/modules/odoo_module>`(使用自定义模块系统)。
大多数新的 Odoo JavaScript 代码应使用原生的 JavaScript 模块系统。它更简单,并且能带来更好的开发者体验,同时与 IDE 的集成也更出色。
声明
/website_airproof/__manifest__.py
¶'assets': {
'web.assets_frontend': [
'website_airproof/static/src/js/theme.js',
],
},
注解
如果你希望包含来自外部库的文件,可以将它们添加到你的模块的 /lib
文件夹中。
小技巧
使用代码检查工具(JSHint,…)。
永远不要添加经过压缩的 JavaScript 库。
在每个 Odoo JavaScript 模块的顶部添加
'use strict';
。变量和函数应使用 驼峰命名法 (
myVariable
),而不是 下划线命名法 (my_variable
)。不要将变量命名为
event
;请改用ev.
。这是为了避免在非 Chrome 浏览器上出现错误,因为 Chrome 会神奇地分配一个全局的 event 变量(因此如果你不声明就使用 event 变量,在 Chrome 上看起来没问题,但在其他浏览器上会崩溃)。使用严格比较(
===
而不是==
)。所有文本字符串(如
"Hello"
)使用双引号,所有其他字符串(如 CSS 选择器.x_nav_item
)使用单引号。始终使用
this._super.apply(this, arguments)
。