基于 Odoo + Python 的网站快速开发指南

基于 Odoo + Python 的网站快速开发指南

在这里插入图片描述

下载根据本指南开发的主题模块源码

Odoo 网站生成器是一个灵活的工具,可以轻松构建与 Odoo 应用完全集成的网站。使用其提供的主题选项 (options) 和构建块 (blocks) 很容易定制网站。然而,你还可以更进一步深度定制。在本文中,您将学习在不修改 Odoo 核心文件的情况下完全自定义您的网站,同时保留网站生成器 (builder) 的设置选项。

准备

  1. Odoo 开发基础知识
    每个 Odoo 应用模块都是类似的,它们是用相同的逻辑构建的。Odoo 的基础是模型。模型使用字段来记录数据,包含基本字段和链接到其他模型的关系字段,每个模型都有表示其所有字段的前端(QWeb)和后端视图(Kanban, List, Form, etc.)。你可以打开开发者模式,然后进入设置>技术>模型 查看模型列表。
  2. Odoo16 VScode 开发环境搭建
  3. 在应用中安装网站 (website) 模块
  4. 打开调试模式
    开发人员模式(也称为调试模式)对于开发非常有用,它允许访问一些隐藏功能。在接下来的章节中,假设您已经启用了开发人员模式。在 URL 的 /web 后添加 ?debug=1?debug=true 。若要停用调试模式,请将该值改为?debug=0。前端开发时还可以使用 ?debug=assets 启用资产模式(刷新页面会重新编译视图),而?debug=tests 启用测试模式(运行测试)。
  5. 了解 QWeb
    Odoo 的主要模板引擎,用于生成 HTML 片段和页面。

一、主题

主题像任何 Odoo 模块一样被打包。即使你在设计一个基本的网站,你也需要把它打包成一个模块。Odoo 有一个默认的主题,提供最小的结构和布局。创建新主题时,您一般是在扩展默认主题。

注意: 首先尝试使用 Odoo 的默认选项来构建主题。这确保了两件事:

  1. 不重新发明已经存在的东西。例如,由于 Odoo 提供了在页脚上添加边框的选项,因此您不应该自己重新编码。相反,应该启用默认选项,在需要时扩展它。
  2. 用户一直可以在您的主题中使用 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-colors.png
在文件 /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

  1. 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>
  1. 通过 $o-website-values-palettes 设置 'header-template': 'odooer', 使用新模板。
  2. 定义新的 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>

响应式

<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">&nbsp;</div>
    <div class="media_iframe_video_size" contenteditable="false">&nbsp;</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),是用户设计和布局页面的方式。构造块分为四类:

  1. 结构块: 给网站一个基本的结构
  2. 特征块: 描述产品或服务的特征
  3. 动态内容块: 与后端动态交互的块
  4. 内部内容块: 可以在其他构造块内部使用的块

查看当前所有构造块: 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-namedata-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-targetdata-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>
Default 01 02
</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_animateo_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_ 开头。

在这里插入图片描述

通过导入模块安装

  1. 创建模块的ZIP文件。
  2. 启用开发者模式。
  3. 安装 base_import_module
  4. 单击菜单中的 导入模块
  5. 上传您的ZIP文件,勾选 强制初始化,然后单击 导入 按钮。

在这里插入图片描述

附录

Odoo 基础:模块开发教程

Win10 Odoo 开发环境搭建

Nginx + Docker 部署 Odoo16

工具推荐