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

news2024/11/25 20:22:23

基于 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',  # 自定义字体
	...
颜色

网站生成器依赖于由五种命名颜色组成的调色板。在主题中定义并确保保持一致。

ColorDescription
o-color-1Primary
o-color-2Secondary
o-color-3Extra
o-color-4Whitish
o-color-5Blackish

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>

响应式

  • 通过 Bootstrap 框架功能实现
    • Bootstrap documentation on responsive breakpoints
    • Bootstrap documentation on display property
  • 字体:
    • 从v4.3.0开始,Bootstrap 提供了启用响应式字体大小的选项,允许文本在设备和视口大小之间更自然地缩放。通过将Sass变量$Enable -responsive-font-sizes更改为true来启用它们。
  • 在移动设备上隐藏特定的<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">&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({
    //
});

网站生成器提供了一些事件,可以使用它们来触发自定义函数。

ventDescription
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

工具推荐

  • oh-my-posh
  • mkdocs
  • mermaid
  • Git 提交规范:约定式提交
  • 生成 ChangeLog
  • odoo 开发规范
  • odoo 提交规范

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1179360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaEE进阶3

传递数组: 当我们请求中,同一个参数有多个时,浏览器就会帮我们封装成一个数组 用逗号进行分割也是可以的(有的浏览器不能直接使用逗号,需要我们去转码) 传递集合: HTTP 状态码(不是后端自定义的) 2XX:成功 3XX:重定向 4XX:客户端错误 5XX:服务器错误 业务状态码:HTTP响应…

第十章 Python 自定义模块及导入方法

系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…

Cookie、Session、Token、JWT 一篇就够了

什么是认证&#xff08;Authentication&#xff09; 通俗地讲就是验证当前用户的身份&#xff0c;证明“你是你自己”&#xff08;比如&#xff1a;你每天上下班打卡&#xff0c;都需要通过指纹打卡&#xff0c;当你的指纹和系统里录入的指纹相匹配时&#xff0c;就打卡成功&a…

git工作流(待续)

一、git git是分布式管理系统和集中式的区别在于每个人具有的本地份数不同&#xff0c;集中式只有一份 分布式 主要是 协同工作 gitlab github 等是git仓库的一个托管平台 二、git安装、初始化 基础配置 第一次需要对身份进行说明 git config --global user.name "xx&…

阿里云安全恶意程序检测(速通二)

阿里云安全恶意程序检测 高阶数据探索变量分析连续数值变量与连续数值变量单个类别变量与连续数值变量两个类别变量与连续数值变量两个变量线性关系探索查看多个双变量关系的技巧 高阶数据探索多变量交叉探索 高阶数据探索 变量分析 连续数值变量与连续数值变量 分析连续数值…

SQL第三次上机作业

1.查询与王利就读同一专业学生的借书证号和姓名 SELECT Lno,Rname FROM Reader WHERE Dept(SELECT DeptFROM ReaderWHERE Rname王利)2.查询比希望出版社出版的所有图书价格都高的图书信息 SELECT * FROM Book WHERE Price>(SELECT MAX(Price)FROM BookWHERE Press希望出版…

【C++入门 四】学习C++内联函数 | auto关键字 | 基于范围的for循环(C++11) | 指针空值nullptr(C++11)

C 入门 四 1.内联函数1.1前言&#xff08;引出内联函数&#xff09;①写一个Add函数的宏定义②宏的缺点③C对宏的态度 1.2内联函数①概念②内联函数特性 2.auto关键字(C11)① 类型别名思考② auto简介③ auto的使用细则④ auto不能推导的场景 3. 基于范围的for循环(C11)① 范围…

【计算机网络笔记】TCP的拥塞控制机制

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

3.27每日一题(常系数线性非齐次方程的特解)

常系数非齐次线性方程的特解如何假设&#xff08;两种&#xff09;形式&#xff1a; 1、题目中 e 的 x 次幂以及 1&#xff0c;都是第一种&#xff1a;1可以看成为e的0次幂 注&#xff1a;题目给的多项式是特殊的形式&#xff0c;我们要设为一般的形式的多项式 2、题目中sin…

git使用全解析 | git的原理 配置 基础使用 分支 合并

文章目录 1 git初步了解1.1 git的安装1.2 git原理模型1.3 git基础配置1.4 git基础用法1 将文件加入暂存区2 查看当前的git仓库状态3 删除文件4 commit 将暂存区文件加入本地git版本仓库5 查看提交历史 更改 2 分支2.1 创建分支2.2 查看分支2.3 切换分支2.4 内容比较 3 合并 本文…

【单片机基础小知识-如何通过指针来读写寄存器】

寄存器的本质就是内存&#xff0c;RAM&#xff0c;而指针是可以对内存进行操作的&#xff0c;因此可以通过指针来读写寄存器。 如何读取以下一片地址&#xff1a; 步骤1、首地址 结构体&#xff0c;它所占用的内存空间大小与它内部成员有关。 构造一个28字节的类型 type…

nginx知识点-1

#因为是最小化安装&#xff0c;先安装vim编辑器&#xff0c;net-tools查看端口&#xff0c;psmisc可以使用killall命令bash-completion tab补全命令(需要重启生效)[rootlocalhost ~]# yum -y install net-tools psmisc vim bash-completion [rootlocalhost ~]# tar zxvf nginx-…

报错Could not resolve placeholder ‘driver‘ in value “${driver}“

这是我的报错&#xff1a; 原因是我的applicationContext.xml文件加载properties文件径错误&#xff1a; 应该把路径改成这样就可以了&#xff1a;

强化学习中值的迭代

一、价值的迭代 策略迭代的一个缺点是&#xff0c;其每次迭代都涉及策略评估&#xff0c;这本身可能是一个漫长的迭代计算&#xff0c;需要多次遍历状态集。如果策略评估是迭代进行的&#xff0c;那么只有当趋近于vπ时才会收敛。我们是否必须等待完全收敛&#xff0c;还是可以…

mac电脑系统清理软件CleanMyMac X2024破解版下载

基本上&#xff0c;不管是win版还是Mac版的电脑&#xff0c;其装机必备就是一款电脑系统清理软件&#xff0c;就比如Mac&#xff0c;目前在市面上&#xff0c;电脑系统清理软件是非常多的。 对于不熟悉系统的用户来说&#xff0c;使用一些小众工具&#xff0c;往往很多用户都不…

如何快速部署Apache服务器并使用内网穿透实现远程连接

Apache服务安装配置与结合内网穿透实现公网访问 文章目录 Apache服务安装配置与结合内网穿透实现公网访问前言1.Apache服务安装配置1.1 进入官网下载安装包1.2 Apache服务配置 2.安装cpolar内网穿透2.1 注册cpolar账号2.2 下载cpolar客户端 3. 获取远程桌面公网地址3.1 登录cpo…

nacos配置中心docker部署、配置及 goLang 集成使用

为什么需要配置中心 平时我们写一个demo的时候&#xff0c;或者说一个单体的应用&#xff0c;都会有一个配置文件&#xff0c;不管是 json文件或者yaml文件&#xff0c;里面包含了redis,mysql,es等信息&#xff0c;如果我们修改了配置文件&#xff0c;往往我们需要重启&#x…

【面试题01】找出数组中的最长前缀

题目1&#xff1a;如图&#xff0c;finally中的输出语句会执行吗&#xff1f;&#xff08;另外自己去考虑虚拟机退出、catch中抛异常、try中抛异常、守护线程等相关问题&#xff09; 题目2&#xff1a;Byte"hello"报错吗&#xff1f;Byte7报错吗&#xff1f; 不会报…

服务器的操作系统,你选择哪些?

OpenCloudOS CentOS CentOS Stream Ubuntu Debian Windows Server

【c++】——类和对象(中)——默认成员函数(上)

【学习目标】 1. 类的6个默认成员函数 2. 构造函数 3. 析构函数 4. 拷贝构造函数 目录 一.类的6个默认成员函数 二. 构造函数 2.1 概念 2.2.特性 三.析构函数 3.1.概念 3.2 特性 四.拷贝构造函数 4.1.概念 4.2.特性 一.类的6个默认成员函数 如果一个类中什么成员…