Odoo 网站主题开发指南
Odoo 网站主题开发指南
Odoo 网站生成器是一个灵活的工具,可以轻松构建与 Odoo 应用完全集成的网站。使用其提供的主题选项 (options) 和构建块 (blocks) 很容易定制网站。然而,你还可以更进一步深度定制。在本文中,您将学习在不修改 Odoo 核心文件的情况下完全自定义您的网站,同时保留网站生成器 (builder) 的设置选项。
准备
- Odoo 开发基础知识
每个 Odoo 应用模块都是类似的,它们是用相同的逻辑构建的。Odoo 的基础是模型。模型使用字段来记录数据,包含基本字段和链接到其他模型的关系字段,每个模型都有表示其所有字段的前端(QWeb)和后端视图(Kanban, List, Form, etc.)。你可以打开开发者模式,然后进入设置>技术>模型
查看模型列表。 - Odoo16 VScode 开发环境搭建
- 在应用中安装网站 (website) 模块
- 打开调试模式
开发人员模式(也称为调试模式)对于开发非常有用,它允许访问一些隐藏功能。在接下来的章节中,假设您已经启用了开发人员模式。在 URL 的/web
后添加?debug=1
或?debug=true
。若要停用调试模式,请将该值改为?debug=0
。前端开发时还可以使用?debug=assets
启用资产模式(刷新页面会重新编译视图),而?debug=tests
启用测试模式(运行测试)。 -
了解 QWeb
Odoo 的主要模板引擎,用于生成 HTML 片段和页面。
一、主题
主题像任何 Odoo 模块一样被打包。即使你在设计一个基本的网站,你也需要把它打包成一个模块。Odoo 有一个默认的主题,提供最小的结构和布局。创建新主题时,您一般是在扩展默认主题。
注意: 首先尝试使用 Odoo 的默认选项来构建主题。这确保了两件事:
- 不重新发明已经存在的东西。例如,由于 Odoo 提供了在页脚上添加边框的选项,因此您不应该自己重新编码。相反,应该启用默认选项,在需要时扩展它。
- 用户一直可以在您的主题中使用 Odoo 的所有功能。如果您重新编码页脚上的边框,您可能会破坏默认选项或使其无法使用,从而给用户带来糟糕的体验。此外,您的代码可能不能像默认选项那样正常工作,因为其他 Odoo 功能可能依赖于它。
主题模块结构
模块主文件夹:./theme_odooer
, 需要在配置的 addons_path
路径中,让 odoo 可以找到该主题模块并安装。
theme_odooer
├── data // 预设,菜单,页面,图像 (`*.xml`)
├── i18n // 翻译,(`*.po`, `*.pot`)
├── lib // 外部库(*.js)
├── static // 自定义资产(*.jpg, .gif, .png, .pdf, *.scss, *.js)
│ ├── description
│ ├── fonts
│ ├── image_shapes // Shapes for images
│ ├── shapes // Shapes for background
│ └── src
│ ├── img
│ │ ├── content // 网站
│ │ └── wbuilder // builder 使用
│ ├── js
│ ├── scss
│ └── snippets // 自定义 blocks
├── views // 自定义视图和模板(*.xml)
├── __init__.py // 表示模块是一个 Python 包,包含模块中各种 Python 的导入指令,一般为空
└── __manifest__.py // 模块的元数据
模块元数据
{
'name': 'Odooer Theme',
'description': '...',
'category': 'Website/Theme',
'version': '15.0.0',
'author': '...',
'license': '...',
'depends': ['website'],
'data': [
# ...
],
'assets': {
# ...
},
}
样式变量
Odoo 声明了许多 CSS 规则,其中大多数可以通过覆盖相关的 SCSS 变量来自定义。为此,创建 primary_variables.scss
文件,并将其添加到 _assets_primary_variables
包中。
'web._assets_primary_variables': [
(
'after',
'website/static/src/scss/primary_variables.scss',
'theme_odooer/static/src/scss/primary_variables.scss'
),
],
通过阅读 odoo 源代码,可以找到与更多选项相关的变量名(一般通过 data-*
绑定变量)。
<we-button title="..."
data-name="..."
data-customize-website-views="..."
data-customize-website-variable="'Sidebar'"
data-img="..."/>
全局变量
在文件 /theme_name/static/src/scss/primary_variables.scss
中,可以通过 $o-website-values-palettes
映射来覆盖全局变量的值。该文件只能定义 SCSS 变量和混合(mixins)的覆盖。
$o-website-values-palettes: (
(
// Templates
// Colors
// Fonts
// Buttons
// ...
),
);
字体
你可以在你的网站上嵌入任何字体,网站生成器自动使它们在字体选择器中可用。
$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>,
...,
),
...,
)
)
使用字体:
$o-website-values-palettes: (
(
'font': '<font-name>',
'headings-font': '<font-name>',
'navbar-font': '<font-name>',
'buttons-font': '<font-name>',
),
);
添加自定义字体 fonts.scss
:
@font-face {
font-family: 'font-name';
src: url('#{$font-path}/file-name.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}
在 __manifest__.py
中声明:
'web.assets_frontend': [
'theme_odooer/static/fonts/fonts.scss', # 自定义字体
...
颜色
网站生成器依赖于由五种命名颜色组成的调色板。在主题中定义并确保保持一致。
Color | Description |
---|---|
o-color-1 | Primary |
o-color-2 | Secondary |
o-color-3 | Extra |
o-color-4 | Whitish |
o-color-5 | Blackish |
在文件 /theme_name/static/src/scss/primary_variables.scss
中定义及使用:
$o-color-palettes: map-merge($o-color-palettes,
(
'odooer-1': (
'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, 'odooer-1');
// 使用调色板
$o-website-values-palettes: (
(
'color-palettes-name': 'odooer-1',
...
网站生成器自动生成五种颜色组合,每种颜色都为背景、文本、标题、链接、主要按钮和次要按钮定义了一种颜色。这些颜色以后可以由用户定制。网站生成器会自动生成一个查看颜色组合的页面: http://localhost:8069/website/demo/color-combinations
Odoo 默认包含 Bootstrap 框架的所有变量和 mixins。如果自定义了一个 Bootstrap 变量,就为整个网站添加了一个通用的样式。使用 _assets_frontend_helpers 包中的专用文件来覆盖 Bootstrap 值,而不是 primary_variables.scss
文件。可通过链接 http://localhost:8069/website/demo/bootstrap 查看当前 Bootstrap 值。
对于某些选项,除了修改 Website Builder 变量之外,您还必须激活特定的视图。
通过阅读源代码,很容易找到与选项相关的模板。
<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"/>
可以在文件 /theme_odooer/data/presets.xml
中调整预设:
<record id="website_sale.products_categories" model="ir.ui.view">
<field name="active" eval="False"/>
</record>
添加自定义 css 或 js
web 模块中的 assets_frontend 指定了网站生成器加载的资产列表,以将 SCSS 和 JS 文件打包。
'web.assets_frontend': [
'theme_odooer/static/fonts/fonts.scss', # 自定义字体
'theme_odooer/static/src/scss/theme.scss',
'theme_odooer/static/src/js/theme.js',
...
建议多数新的 Odoo JavaScript 代码应该使用原生 JavaScript 模块系统。它更简单,并且通过与IDE更好的集成带来了更好的开发人员体验。Odoo 将查看 JS 文件的第一行,是否包含字符串 @odoo-module
。如果是,它将自动转换为 Odoo 模块。更多参考 Odoo Javascript Modules
/** @odoo-module */
import { someFunction } from "./file_b";
export function otherFunction(val) {
return someFunction(val + 3);
}
二、布局
这一部分介绍如何自定义 header、footer, 以及如何扩展模板,添加版权部分,提高网站的自适应能力。
Odoo页面结合了跨页面和独有元素。跨页面元素在每个页面上都是相同的,而独有元素仅与特定页面相关。默认情况下,页面有两个跨页面元素:页眉和页脚,以及包含该页特定内容的独有元素。
<div id="wrapwrap">
<header/>
<main>
<div id="wrap" class="oe_structure">
<!-- Page Content -->
</div>
</main>
<footer/>
</div>
XPath 介绍
XPath (XML路径语言)是一种表达式语言,它使您能够轻松地浏览 XML 文档中的元素和属性。XPath 用于扩展标准 Odoo 模板。对于每个 XPath,通过两个属性:表达式(expr)和位置(position)来指定修改范围。扩展默认主题时,您的更改将优先于任何未来的 Odoo 更新。更多参考
<template id="layout" inherit_id="website.layout" name="Welcome Message">
<xpath expr="//header" position="before">
<!-- Content 在页面内容之前添加一条欢迎消息。-->
</xpath>
</template>
注意:继承视图的 XML ID 应该使用与原始记录相同的 ID。它有助于一目了然地找到所有的继承。由于最终的 id 以创建它们的模块为前缀,因此不会冲突。
- XPath 表达式 expr:使用选择器来定位正确的元素。
层级选择器 | 说明 |
---|---|
/ | 选择根节点。 |
// | 当前节点下所有能匹配的节点。 |
属性选择器 | 说明 |
---|---|
* |
选择任何 XML 标记。如果需要更精确的选择,* 可以被一个特定的标签代替。 |
*[@id=”id”] |
根据 id 选择 |
*[hasclass(“class”) ] |
根据样式类选择 |
*[@name=”name”] |
根据标签名选择 |
*[@t-call=”t-call”] |
选择一个具体的 t-call |
示例:
该XPath在<header>
的直接子元素<nav>
之前添加了<div>
:
<xpath expr="//header/nav" position="before">
<div>Some content before the header</div>
</xpath>
这个 XPath 在 header 的 class 属性中添加了 .x_airproof_header 。还需要定义一个分隔符属性,在添加的类之前添加一个空格:
<xpath expr="//header" position="attributes">
<attribute name="class" add="x_airproof_header" separator=" "/>
</xpath>
这个 XPath 删除了 header 的 class 中的 x_airproof_header:
<xpath expr="//header" position="attributes">
<attribute name="class" remove="x_airproof_header" />
</xpath>
这个 XPath 删除了带有 .breadcrumb 类的第一个元素。
<xpath expr="//*[hasclass('breadcrumb')]" position="replace"/>
这个 XPath 在 ul 元素的最后一个子元素之后添加了一个额外的 li 元素:
<xpath expr="//ul" position="inside">
<li>Last element of the list</li>
</xpath>
自定义 Header
默认情况下,标题包含响应式导航菜单和公司 logo,还可以添加新元素或创建自己的模板。
方式一、调整默认 header, 并禁用旧活动头模板,并启用要使用的模板。
$o-website-values-palettes: (
(
'header-template': 'Contact',
...
方式二、添加新的 header
- 在
theme_odooer/data/presets.xml
为网站生成器添加模板选项,名称为Odooer
图标为header_template_odooer.svg
:
<template id="template_header_opt" inherit_id="website.snippet_options" name="Header Template - Option">
<xpath expr="//we-select[@data-variable='header-template']" position="inside">
<we-button title="Odooer"
data-customize-website-views="theme_odooer.header"
data-customize-website-variable="'odooer'" data-img="/theme_odooer/static/src/img/header_template_odooer.svg"/>
</xpath>
</template>
- 通过
$o-website-values-palettes
设置'header-template': 'odooer',
使用新模板。 - 定义新的 header 模板
/theme_odooer/views/website_templates.xml
, 可以使用 QWeb 的t-call、t-set
指令使用website.*
模板,修改设置。
<record id="header_template_odooer" model="ir.ui.view">
<field name="name">Odooer Header</field>
<field name="type">qweb</field>
<field name="key">theme_odooer.header_template_odooer</field>
<field name="inherit_id" ref="website.layout"/>
<field name="mode">extension</field>
<field name="active" eval="True"/>
<field name="arch" type="xml">
<xpath expr="//header//nav" position="replace">
<t t-call="website.navbar">
<t t-set="_navbar_classes" t-valuef="shadow-sm"/>
<div id="top_menu_container" class="container justify-content-start justify-content-lg-between">
<!-- Brand -->
<t t-call="website.placeholder_header_brand">
<t t-set="_link_class" t-valuef="me-4"/>
</t>
...
自定义 footer
默认情况下,页脚包含一个含静态内容的节,可以通过网站编辑器直接修改。跟 head 一样也可以调整默认的footer,或添加自定义footer。
版权
目前版权栏只有一个模板可用
<template id="copyright" inherit_id="website.layout">
<xpath expr="//div[hasclass('o_footer_copyright')]" position="replace">
<div class="o_footer_copyright" data-name="Copyright">
<!-- Content -->
</div>
</xpath>
</template>
拖放区
不需要定义页面的完整布局,可以定义一个空白区域,您可以添加构建块(snippets),并让用户决定拖放填充,我们称之为模块化设计。
使用 oe_structure
为用户定义一个拖放区域。在 oe_structure_solo
区域中只能放置一个构建块。
<div id="oe_structure_layout_01" class="oe_structure"/>
还可以用您的内容填充现有的拖放区:
<template id="oe_structure_layout_01" inherit_id="..." name="...">
<xpath expr="//*[@id='oe_structure_layout_01']" position="replace">
<div id="oe_structure_layout_01" class="oe_structure oe_structure_solo">
<!-- Content -->
</div>
</xpath>
</template>
响应式
- 通过 Bootstrap 框架功能实现
- 字体:
- 从v4.3.0开始,Bootstrap 提供了启用响应式字体大小的选项,允许文本在设备和视口大小之间更自然地缩放。通过将Sass变量
$Enable -responsive-font-sizes
更改为true来启用它们。
- 从v4.3.0开始,Bootstrap 提供了启用响应式字体大小的选项,允许文本在设备和视口大小之间更自然地缩放。通过将Sass变量
- 在移动设备上隐藏特定的
<section>
<section class="d-none d-md-block">
<!-- Content -->
</section>
- 在移动设备上隐藏特定的列
col-*
<section>
<div class="container">
<div class="row d-flex align-items-stretch">
<div class="col-lg-4 d-none d-md-block">
<!-- Content -->
</div>
</div>
</div>
</section>
三、导航
Odoo 会根据你安装的应用自动生成一些基本的菜单项。例如,网站应用程序在主菜单中添加了两个项目。这些项目链接到页面,这些页面也是自动创建的。
- 删除自动生成的默认菜单
/data/menu.xml
:
<!-- Contact us -->
<delete model="website.menu" search="[('url','in', ['/', '/contactus']),
('website_id', '=', 1)]"/>
<!-- Shop -->
<delete model="website.menu" search="[('url','in', ['/', '/shop']),
('website_id', '=', 1)]"/>
- 添加菜单:
<record id="menu_about_us" model="website.menu">
<field name="name">About us</field>
<field name="url">/about-us</field>
<field name="parent_id" search="[
('url', '=', '/default-main-menu'),
('website_id', '=', 1)]"/>
<field name="website_id">1</field>
<field name="sequence" type="int">10</field>
</record>
- 设置在新标签页打开页面:
<field name="new_window" eval="True"/>
- 打开外部链接:
<field name="url">https://www.aaronzzh.cn</field>
- 链接到页面的特定部分:
<field name="url">/about-us#our-team</field>
- 添加到下拉菜单项目:
<record id="menu_services_item_1" model="website.menu">
<field name="name">Item 1</field>
<field name="url">/dropdown/item-1</field>
<field name="website_id">1</field>
<field name="parent_id" ref="website_airproof.menu_services"/>
<field name="sequence" type="int">...</field>
</record>
- 添加超级菜单,类似下拉菜单,内容不仅仅是链接列表。可以使用任何类型的内容(文本,图像,图标等):
<record id="menu_mega_menu" model="website.menu">
<field name="name">Mega Menu</field>
<field name="url">/mega-menu</field>
<field name="parent_id" search="[
('url', '=', '/default-main-menu'),
('website_id', '=', 1)]"/>
<field name="website_id">1</field>
<field name="sequence" type="int">..</field>
<field name="is_mega_menu" eval="True"/>
<field name="mega_menu_classes">...</field>
<field name="mega_menu_content" type="html">
<!-- Content -->
</field>
</record>
自定义超级菜单内容
<template id="s_mega_menu" name="Mega" groups="base.group_user">
<section class="s_mega_menu o_cc o_cc1 pt40">
<!-- Content -->
</section>
</template>
使用以下代码在网站生成器上为 mega 菜单添加选项:
<template id="snippet_options" inherit_id="website.snippet_options" name="Airproof - Mega Menu Options">
<xpath expr="//*[@data-name='mega_menu_template_opt']/*" position="before">
<t t-set="_label">Mega Item</t>
<we-button t-att-data-select-label="_label"
data-select-template="theme_odooer.s_mega_menu"
data-img="/s_mega_menu/static/src/img/builder/header_opt.svg"
t-out="_label"/>
</xpath>
</template>
四、页面
在 Odoo 中,网站有一些默认的静态页面(主页,联系我们,404),可通过下面的方式定义
<template id="website.homepage" name="Homepage">
<t t-call="website.layout">
<!-- Variables -->
<t t-set="additional_title" t-value="'Home'" />
<div id="wrap" class="oe_structure oe_empty">
<!-- Content -->
</div>
</t>
</template>
- 设置变量值
<t t-set="additional_title" t-value="'...'"/>
<t t-set="meta_description" t-value="'...'"/>
<t t-set="pageName" t-value="'...'"/>
<t t-set="no_header" t-value="true"/>
<t t-set="no_footer" t-value="true"/>
- 隐藏页面
<record id="website.homepage" model="ir.ui.view">
<field name="active" eval="False"/>
</record>
- 修改页面内容
<template id="404" inherit_id="http_routing.404">
<xpath expr="//*[@id='wrap']" position="replace">
<t t-set="additional_title" t-value="'404 - Not found'"/>
<div id="wrap" class="oe_structure">
<!-- Content -->
</div>
</xpath>
</template>
- 创建自定义页面, 调用
<t t-call="website.layout">
使用 Odoo 的默认页面布局
<record id="page_about_us" model="website.page">
<field name="name">About us</field>
<field name="is_published" eval="True"/>
<field name="key">theme_odooer.page_about_us</field>
<field name="url">/about-us</field>
<field name="type">qweb</field>
<field name="arch" type="xml">
<t t-name="website_airproof.page_about_us">
<t t-call="website.layout">
<div id="wrap" class="oe_structure">
<!-- Content -->
</div>
</t>
</t>
</field>
</record>
图像
- 添加图像文件
/data/images.xml
<record id="img_about_01" model="ir.attachment">
<field name="name">About Image 01</field>
<field name="datas" type="base64" file="theme_odooer/static/src/img/img_about_01.jpg"/>
<field name="res_model">ir.ui.view</field>
<field name="public" eval="True"/>
</record>
- 使用作为背景图像,图片大小对用户体验、搜索引擎优化和网站性能有很大影响。一定要注意调整图像的大小。
<section style="background-image: url('/web/image/theme_odooer.img_about_01');">
<!--添加滤镜-->
<img src="/web/image/website.s_media_list_default_image_1"
class="img img-fluid mx-auto" alt=""
data-gl-filter="custom"
data-filter-options="{'filterColor': 'rgba(0, 0, 0, 0.5)'}"/>
视频
- 使用视频作为背景
<section class="o_background_video" data-bg-video-src="...">
<!-- Content -->
</section>
- 使用视频作为内容
<div class="media_iframe_video" data-oe-expression="...">
<div class="css_editable_mode_display"> </div>
<div class="media_iframe_video_size" contenteditable="false"> </div>
<iframe src="..."
frameborder="0"
contenteditable="false"
allowfullscreen="allowfullscreen"/>
</div>
图标
默认情况下,Awesome 图标库包含在网站生成器中。可以使用 CSS 前缀 fa
和图标的名称来添加图标。为简洁起见,您可以使用<i>
标记,但使用<span>
在语义上更正确。增加图标大小 (fa-2x、fa-3x、fa-4x或fa-5x)。
<span class="fa fa-picture-o"/>
五、构造块 blocks
构造块(blocks),也称为(snippets),是用户设计和布局页面的方式。构造块分为四类:
- 结构块: 给网站一个基本的结构
- 特征块: 描述产品或服务的特征
- 动态内容块: 与后端动态交互的块
- 内部内容块: 可以在其他构造块内部使用的块
查看当前所有构造块: http://localhost:8069/website/demo/snippets
目录结构
构造块视图文件目录结构:
views
├── snippets
│ └── options.xml
│ └── s_snippet_name.xml
样式文件目录结构:
static
├── src
│ └── snippets
│ └── options.scss
│ └── s_snippet_name
│ └── 000.js
│ └── 000.scss
│ └── 000.xml
│ └── option.js
构造块结构
用户可以使用网站生成器编辑构造块, 一些 class 很重要,因为它们会触发一些网站生成器选项。
Wrapper
构造块的标准主容器是 <section>
, section 元素都可以像内容块一样进行编辑、移动或复制。对于内部构造快,可以使用任何其他 HTML 标记。系统根据模板的名称在拖放过程中会自动添加 data-name
和 data-snippet
属性。
<section class="s_snippet_name" data-name="..." data-snippet="...">
<!-- Content -->
</section>
当在主题页面上声明 snippet 时,应该添加上面这些属性。避免在 section 标签中添加另一个 section 标签,这会触发两次网站生成器的选项。您可以使用内部构造块。
行列
任何大的 Bootstrap .row 下的列 .col , 将由网站生成器使它们可调整大小。
- 使用
class="pt80 pb80"
调整 padding - 使用
class="o_cc o_cc*"
根据调色板调整背景色 - 使用
<div class="o_not_editable">
可以使元素不可编辑 - 使用
<div class="container s_allow_columns">
使容器可设置列,<div class="row s_nb_column_fixed">
使列选项不可修改 - 使用
class="*_no_resize *_no_bgcolor"
可禁用所有子列或指定子列的大小、背景选项 - 添加滚动视差效果(parallax ):
<section class="parallax s_parallax_is_fixed s_parallax_no_overflow_hidden" data-scroll-background-ratio="1">
<span class="s_parallax_bg oe_img_bg o_bg_img_center" style="background-image: url('...'); background-position: 50% 75%;"/>
<div class="container">
<!-- Content -->
</div>
</section>
- 添加一个不透明度为50%的黑色滤镜, 或通过
style="background-color: rgba(39, 110, 114, 0.54) !important;"
设置自定义颜色。
<section>
<div class="o_we_bg_filter bg-black-50"/>
<div class="container">
<!-- Content -->
</div>
</section>
样式
当构造块具有 data-vcss|data-vxml
属性时,意味着它使用了新版本文件。
自定义构造块
在文件 views/snippets/s_odooer_demo_snippet.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="s_odooer_demo_snippet" name="Odooer Demo snippet">
<section class="s_odooer_demo_snippet">
<!-- Content -->
</section>
</template>
</odoo>
将自定义构造块添加到列表中,这样用户就可以直接从编辑面板将其拖放到页面上。
<template id="snippets" inherit_id="website.snippets" name="Custom Snippets">
<xpath expr="//*[@id='default_snippets']" position="before">
<t id="x_theme_snippets">
<div id="x_theme_snippets_category" class="o_panel">
<div class="o_panel_header">Theme</div>
<div class="o_panel_body">
<t t-snippet="theme_odooer.s_airproof_snippet" t-thumbnail="/theme_odooer/static/src/img/wbuilder/s_airproof_snippet.svg">
<keywords>Snippet</keywords>
</t>
</div>
</div>
</t>
</xpath>
</template>
构造块选项
选项允许用户使用网站生成器可视化编辑构造块的外观。选项通过分组管理,分组上有定义选项如何与用户界面交互的属性。
-
data-selector
可以将组中包含的所有选项绑定到特定元素,可以配合data-target
和data-exclude
使用:
<!-- Options group-->
<div data-selector="section, h1, .custom_class, #custom_id">
...
-
data-js
用于绑定自定义 JavaScript 方法 -
data-drop-in
定义了可以将哪些构造块放入其中 -
data-drop-near
定义了可以将哪些构造块放在旁边
SCSS 选项
选项可以对构造块应用标准或自定义 CSS 类。根据您选择的方法,用户界面的行为会有所不同。
-
data-select-class
定义了用户可以选择的类列表, 一次只能启用一个选项
<template id="snippet_options" inherit_id="website.snippet_options" name="...">
<xpath expr="." position="inside">
<div data-selector="h1, h2, h3, h4, h5, h6">
<we-select string="Headings">
<we-button data-select-class="">Default</we-button>
<we-button data-select-class="x_custom_class_01">01</we-button>
<we-button data-select-class="x_custom_class_02">02</we-button>
</we-select>
</div>
</xpath>
</template>
</xpath>
自定义 javascript
通过 <div data-js="CustomMethodName" data-selector="...">
绑定:
/** @odoo-module */
import options from 'web_editor.snippets.options';
options.registry.CustomMethodName = options.Class.extend({
//
});
网站生成器提供了一些事件,可以使用它们来触发自定义函数。
vent | Description |
---|---|
start | 当用户首次选择构造块或将其拖放到页面上时发生 |
onFocus | 每次用户选择构造块或在页面上拖放构造块时发生 |
onBlur | 失去焦点时发生 |
onClone | 复制时发生 |
onRemove | 删除时发生 |
onBuilt | 在拖放区域上拖放构造块之后发生,触发此事件时,内容已经插入到页面中。 |
cleanForSave | 保存该页之前发生 |
动态构造块
默认情况下,在网站生成器中有一系列动态构造块模板,也将添加自己的动态模板。id 必须以固定格式 dynamic_filter_template_*
开头,例如访问博客数据:
<template id="dynamic_filter_template_blog_post_odooer" name="...">
<div t-foreach="records" t-as="data" class="s_blog_posts_post">
<t t-set="record" t-value="data['_record']"/>
<!-- Content -->
</div>
</template>
还可以通过一些属性调整显示数量:data-number-of-elements*
六、Shapes 图形
通过图形可以对网站进行个性化设置,添加标准和自定义背景和图像形状。
Background shapes
背景形状是SVG文件,您可以将其添加到不同部分中作为装饰背景。每个形状都有一个或几个可定制的颜色,其中一些具有动画效果。
通过 data-oe-shape-data
添加 Shape 图型:
<section data-oe-shape-data="{'shape':'web_editor/Zigs/06'}">
<div class="o_we_shape o_web_editor_Zigs_06"/>
<div class="container">
<!-- Content -->
</div>
</section>
使X或Y轴水平或垂直翻转形状:
<div class="o_we_shape o_we_flip_x o_we_flip_y o_web_editor_Zigs_06"/>
注意: 修改 .xml 中模板后,有时需要删除构造块重新添加。
在 /static/src/scss/boostrap_overridden.scss
中可修改图形默认颜色:
// 将图形 Zigs/06 颜色 4,5 修改为 3,1
$o-bg-shapes: change-shape-colors-mapping('web_editor', 'Zigs/06', (4: 3, 5: 1));
// 或增加图形 Zigs/06 颜色映射
$o-bg-shapes: add-extra-shape-colors-mapping('web_editor', 'Zigs/06', 'second', (4: 3, 5: 1));
Image shapes
图像形状是 SVG 文件,您可以将其作为剪切蒙版添加到图像上。有时更改后可能无法应用图像形状,可开网站生成器并保存页面以强制加载图形。
<img src="..."
class="img img-fluid mx-auto"
alt="..."
data-shape="web_editor/solid/blob_2_solid_str"
data-shape-colors="#35979C;;;;"
>
七、Gradients 渐变
可以为段或标题添加渐变,或添加自定义渐变到网站生成器调色板。可以直接从网站生成器中选择渐变。但是,对于自定义主题,您必须直接在带有 style 属性的 section 标记中添加渐变。
<section class="s_text_image" data-snippet="s_text_image" data-name="Text - Image" style="background-image: linear-gradient(135deg, rgb(255, 204, 51) 0%, rgb(226, 51, 255) 100%) !important;">
<!-- Content -->
</section>
<h2>
<font class="text-gradient" style="background-image: linear-gradient(135deg, rgb(203, 94, 238) 0%, rgb(75, 225, 236) 100%);">A Section Subtitle</font>
</h2>
添加自定义渐变色:
<record id="colorpicker" model="ir.ui.view">
<field name="key">website_airproof.colorpicker</field>
<field name="name">Custom Gradients</field>
<field name="type">qweb</field>
<field name="inherit_id" ref="web_editor.colorpicker"/>
<field name="website_id">1</field>
<field name="arch" type="xml">
<xpath expr="//*[@data-name='predefined_gradients']/*" position="before">
<button class="w-50 o_we_color_btn" style="background-image: linear-gradient(145deg, rgb(5, 85, 94) 0%, rgb(0, 131, 148) 100%);" data-color="linear-gradient(145deg, rgb(5, 85, 94) 0%, rgb(0, 131, 148) 100%)"></button>
</xpath>
</field>
</record>
八、动画
在标准情况下,您可以在元素出现时添加动画,Odoo 有大量的动画可供选择。定义动画需要两个类: o_animate
和 o_anim_fade_in
。第二个类的变化取决于使用的动画类型。可添加o_animate_both_scroll
,在每次列出现在屏幕上时都启动动画。默认情况下,动画只启动一次。可以直接在 style 属性中定义动画持续时间和动画延迟。
<div class="col-lg-6 o_animate o_anim_fade_in o_animate_both_scroll" style="animation-duration: 2s !important; animation-delay: 1s !important;">
<h2>A Section Subtitle</h2>
<p>Write one or two paragraphs describing your product or services.</p>
</div>
九、表单
表单可直接与其他应用程序集成,可用于许多不同的目的。可以在自定义主题中添加表单,更改表单的动作,借助 Bootstrap 变量对表单进行样式化。
- 可通过网站生成器添加表单
- 通过代码向页面添加表单:
<form action="/website/form/" method="post" enctype="multipart/form-data" class="o_mark_required" data-mark="*" data-pre-fill="true" data-success-mode="redirect" data-success-page="/contactus-thank-you" data-model_name="mail.mail">
<div class="s_website_form_rows row s_col_no_bgcolor">
<div class="form-group s_website_form_field col-12 s_website_form_dnone" data-name="Field">
<!-- form fields -->
</div>
</div>
</form>
表单提交动作
表单属性中的 data-model_name,能够为表单定义不同的操作。默认为发送电子邮件(生成 mail.mail 记录并发送邮件)。
还可以:
Apply for a job.
<form data-model_name="hr.applicant">
Create a customer.
<form data-model_name="res.partner">
Create a ticket.
<form data-model_name="helpdesk.ticket">
Create an opportunity.
<form data-model_name="crm.lead">
Create a task.
<form data-model_name="project.task">
可以定义表单提交后的处理,如将用户重定向到 data-success-page 中指定的页面:
<form data-success-mode="redirect" data-success-page="/contactus-thank-you">
或者显示一条消息:
<form data-success-mode="message">
可以直接在表单标记下添加成功消息。并添加 d-none 类,确保在表单尚未提交时隐藏消息。
<div class="s_website_form_end_message d-none">
<div class="oe_structure">
<section class="s_text_block pt64 pb64" data-snippet="s_text_block">
<div class="container">
<h2 class="text-center">This is a success!</h2>
</div>
</section>
</div>
</div>
表单样式
表单默认样式可以通过 bootstrap 变量调整。/static/src/scss/bootstrap_overridden.scss
十、翻译
使网站支持多种语言
添加语言后,点击右上角翻译按钮,有些文本会自动翻译并以绿色高亮显示,而所有需要手动翻译的文本则以黄色高亮显示。可以通过网站生成器修改文字为对应语言。注意:最好是从英文翻译到其他语言。
直接从后端翻译页面允许您同时翻译几种语言。要做到这一点,进入设置>技术>用户界面:视图,搜索你要翻译的页面名称,然后点击编辑翻译按钮。
推荐通过编辑或自己创建 .po 文件进行翻译,先导出.dot, 使用工具 Poedit 翻译每一项生成 .do 文件,更多参考 Odoo 翻译文档。
#. module: theme_odooer
#: model_terms:ir.ui.view,arch_db:theme_odooer.s_custom_snippet
msgid "..."
msgstr "..."
最后、安装主题
通过主题安装
在网站应用点击编辑按钮,打开网站生成器,在主题选项卡最下方,点击切换主题。注意:模块名需以 theme_
开头。
通过导入模块安装
- 创建模块的ZIP文件。
- 启用开发者模式。
- 安装 base_import_module
- 单击菜单中的
导入模块
。 - 上传您的ZIP文件,勾选
强制初始化
,然后单击导入
按钮。
附录
Odoo 基础:模块开发教程
Win10 Odoo 开发环境搭建
Nginx + Docker 部署 Odoo16
工具推荐
- oh-my-posh
- mkdocs
- mermaid
- Git 提交规范:约定式提交
- 生成 ChangeLog
- odoo 开发规范
- odoo 提交规范