积木

构建块(也称为片段)是用户设计和布局页面的方式。它们是设计中重要的 XML 元素。

构建块分为两种类型:

  1. 结构块:视觉上用作“整行”并分布到多个类别(IntroColumnsContentImagesPeople 等)

  2. 内部内容块:在其他构建块内部使用

在本章结束时,您将能够 create custom snippets 并将它们添加到专用类别中。

文件结构

视图模板位于 views/snippets/ 下:

views
└── snippets
    ├── snippets.xml
    └── s_snippet_name.xml

客户端资产位于 static/src/ 下,并按用途分组:

static
└── src
   ├── snippets
   │   └── s_snippet_name
   │       ├── snippet_name.js
   │       ├── snippet_name.edit.js
   │       ├── 000.scss
   │       └── 000.xml
   └── website_builder
       ├── snippet_name_option.js
       ├── snippet_name_option.xml
       └── snippet_name_option_plugin.js

小技巧

/snippets 下的 JS 文件是交互:examples_floating_blocks 代码段和基本 Interaction 类。

演示页面

必须安装演示数据才能访问此页面:

https://your-database.com/website/demo/snippets

布局

用户可以使用网站生成器编辑片段。一些 Bootstrap 类很重要,因为**它们会触发一些网站生成器选项**。

包装纸

任何代码片段的标准主容器都是 section。任何部分元素都可以像可以移动或复制的内容块一样进行编辑。

<section class="s_snippet_name" data-name="..." data-snippet="...">
   <!-- Content -->
</section>

对于内部内容片段,可以使用任何其他 HTML 标签。

<div class="s_snippet_name" data-name="..." data-snippet="...">
   <!-- Content -->
</div>

属性

描述

班级

此片段的唯一类名

数据名称

在右侧面板中显示为片段的名称。如果没有找到,它将回退到*Block*。

数据片段

系统使用它来识别片段

系统在拖放过程中根据模板名称自动添加 data-namedata-snippet 属性。

警告

当在主题页面上声明代码片段时,应专门添加这些属性。

警告

避免在另一个 section 标签内添加 section 标签:这将触发网站构建器选项的两倍。您可以使用内部内容片段来代替。

小技巧

要使用标准片段编写静态页面的内容,有两种可能的方法:

  • 使用网站生成器预构建自定义静态页面: 拖放片段,然后

    将代码复制/粘贴到您的文件中并清理它。

或者
  • 直接对所有内容进行编码: 但要注意与网站生成器的兼容性。它

    需要某些类、名称、id、数据等才能正常工作。一个好的做法是在 Odoo 源文件中查找以标准代码创建的片段代码。请注意,网站生成器有时会在放入页面后向片段添加类。

元素

我们可以使用特定的 CSS 类来启用/禁用一系列“功能”。

浆纱

任何直接从 .row 元素(尊重 Bootstrap 结构)下降的大型 Bootstrap 列都将由网站生成器触发,以使其可调整大小。

.row > .col-lg-*

在列和 <section> 上添加填充。

class="pt80 pb80"

注解

pb*pt* 是用于控制处理程序的 Odoo 类。它们的值增加**8的倍数**,直到**最大值为256**(0、8、16、24、32、40、48,…)。

启用列选择器。

<div class="container s_allow_columns">

禁用列数量选项。

<div class="row s_nb_column_fixed">

禁用所有子列的大小选项。

<div class="row s_col_no_resize">

禁用某一特定列的大小选项。

<div class="col-lg-* s_col_no_resize">

颜色

根据列和 <section> 的调色板添加背景。

class="o_cc o_cc*"

禁用所有列的背景颜色选项。

<div class="row s_col_no_bgcolor">

禁用某一特定列的背景颜色选项。

<div class="col-lg-* s_col_no_bgcolor">

添加不透明度为 50% 的黑色滤镜。

<section>
   <div class="o_we_bg_filter bg-black-50" />
   <div class="container">
      <!-- Content -->
   </div>
</section>

添加不透明度为 85% 的白色滤色镜。

<section>
   <div class="o_we_bg_filter bg-white-85" />
   <div class="container">
      <!-- Content -->
   </div>
</section>

添加自定义滤色镜。

<section>
   <div class="o_we_bg_filter" style="background-color: rgba(39, 110, 114, 0.54) !important;" />
   <div class="container">
      <!-- Content -->
   </div>
</section>

添加自定义渐变滤镜。

<section>
   <div class="o_we_bg_filter" style="background-image: linear-gradient(135deg, rgba(255, 204, 51, 0.5) 0%, rgba(226, 51, 255, 0.5) 100%) !important;" />
   <div class="container">
      <!-- Content -->
   </div>
</section>

特征

不可编辑区域

使元素不可编辑。

<div class="o_not_editable">

使元素不可移动。

<div class="oe_unremovable">
背景

添加背景图像并将其居中。

<div class="oe_img_bg o_bg_img_center" style="background-image: url('...')">

添加视差效果。

<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>

注解

可以在某个部分上设置视频背景。请参阅本文档的 Media 章节。

文字亮点

文本突出显示是 SVG 文件,可以将其合并到特定单词或短语中以对其进行强调。文本突出显示提供可自定义的颜色和厚度选项。

文本突出显示示例
<h2>
   Title with
   <span
      class="o_text_highlight o_text_highlight_fill"
      style="--text-highlight-width: 10px !important; --text-highlight-color: #FFFF00;">
      <span class="o_text_highlight_item">
         highlighted text
         <svg fill="none" class="o_text_highlight_svg o_content_no_merge position-absolute overflow-visible top-0 start-0 w-100 h-100 pe-none">
            <!-- SVG path -->
         </svg>
      </span>
   </span>
</h2>

CSS 自定义属性

描述

--text-highlight-width

SVG 边框的厚度

--text-highlight-color

SVG 对象的颜色

网格布局

网格布局是 CSS 中强大而灵活的布局系统,使用户能够轻松设计复杂的构建块布局。

使用

通过在 row 上添加 o_grid_mode CSS 类来启用网格布局。网格中的行数由 data-row-count 属性定义。网格始终包含 12 列。在 style 属性中指定的网格间隙确定行和列之间的间隙(或间距)。

<div class="row o_grid_mode" data-row-count="13" style="gap: 20px 10px">
   <!-- Content -->
</div>

网格中的项目

使用 o_grid_item 类在网格中添加项目。如果网格项包含图像,请使用 o_grid_item_image 类。

<div class="row o_grid_mode" data-row-count="13">
   <div class="o_grid_item g-height-* g-col-lg-*" style="grid-area: 2 / 1 / 7 / 8; z-index: 3;">
      <!-- Content -->
   </div>
   <div class="o_grid_item o_grid_item_image g-height-* g-col-lg-*" style="grid-area: 1 / 6 / 9 / 13; z-index: 2;">
      <img src="..." alt="..." >
   </div>
</div>

网格项的尺寸和位置由网格区域定义,网格区域可以与 z 索引一起在 style 属性中显式设置。

g-height-*g-col-lg-* 类由网站生成器生成用于编辑目的。

网格项目填充

<div class="row o_grid_mode" data-row-count="13" style="gap: 20px 10px;">
   <div class="o_grid_item g-height-* g-col-lg-*" style="--grid-item-padding-y: 20px; --grid-item-padding-x: 15px; grid-area: 2 / 1 / 7 / 8; z-index: 3;">
      <!-- Content -->
   </div>
</div>

CSS 自定义属性

描述

--grid-item-padding-y

垂直内边距(Y 轴)

--grid-item-padding-x

水平填充(X 轴)

兼容系统

当代码片段具有 data-vcssdata-vjs 和/或 data-vxml 属性时,意味着它是更新的

版本,不是原来的版本。

<section class="s_snippet_name" data-vcss="001" data-vxml="001" data-vjs="001">
   <!-- Content -->
</section>

这些数据属性向系统指示要为该片段加载哪个文件版本(例如 001.js002.scss)。

自定义片段

一些更具体的需求将需要创建自定义片段。以下是如何创建自定义片段/

模板

首先创建片段模板。然后,将其添加到列表中并通过网站生成器使其可用。

1. 声明

首先,创建自定义代码片段的模板:

/website_airproof/views/snippets/s_airproof_snippet.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>

   <template id="s_airproof_snippet" name="...">
      <section class="s_airproof_snippet">
         <!-- Content -->
      </section>
   </template>

</odoo>

警告

在主题页面上声明代码片段时,必须指定 data-namedata-snippet 属性。否则,网站生成器将无法识别该代码段,并且每当完成数据库升级时都可能会出现问题。此外,请记住,名称属性在选项面板的 Blocks 部分中显示为自定义代码段的名称。

小技巧

  • 尽可能使用 Bootstrap 本机类。

  • 为所有自定义类添加前缀。

  • 使用下划线小写表示法来命名类,例如 .x_nav.x_nav_item

  • 避免在 section 中使用 ID 属性,因为整个页面中可能会出现多个代码片段实例(ID 属性在页面上必须是唯一的)。

将自定义代码段添加到标准代码段列表中,以便用户可以直接从编辑面板将其拖放到页面上。

2. 群组创建

在列表顶部添加一个组(随意将其放置在此列表中需要的位置)。

/website_airproof/views/snippets/snippets.xml
<template id="snippets" inherit_id="website.snippets" name="Airproof - Snippets">
   <!-- Create the group -->
   <xpath expr="//snippets[@id='snippet_groups']/*[1]" position="before">
      <t snippet-group="airproof"
         t-snippet="website.s_snippet_group"
         string="Airproof"
         t-thumbnail="/website_airproof/static/src/img/wbuilder/s_airproof_group_thumbnail.svg" />
   </xpath>
</template>

属性

描述

片段组

群组ID

T 片段

继承的模板ID

细绳

显示给用户的组名称

T 缩略图

组缩略图的路径

1. 片段添加

然后将自定义代码段添加到 <snippets id="snippet_structure"> 中,其中包含同一级别上的所有现有代码段。网站生成器将通过读取 <t t-snippet=""> 上的 group 属性自动将它们分为几类

/website_airproof/views/snippets/snippets.xml
<template id="snippets" inherit_id="website.snippets" name="Airproof - Snippets">
   <!-- Create the group -->
   <xpath expr="//snippets[@id='snippet_groups']/*[1]" position="before">
      <t snippet-group="airproof"
         t-snippet="website.s_snippet_group"
         string="Airproof" t-thumbnail="/website_airproof/static/src/img/wbuilder/s_airproof_group_thumbnail.svg" />
   </xpath>

   <!-- Add the custom snippet to the group -->
   <xpath expr="//snippets[@id='snippet_structure']/*[1]" position="before">
      <t t-snippet="website_airproof.s_airproof_snippet" string="Custom snippet" group="airproof">
         <keywords>Snippet</keywords>
      </t>
   </xpath>
</template>

属性

描述

T 片段

要使用的片段模板

团体

添加代码片段的组。

<关键字>

用户在“片段”面板的搜索字段中输入的关键字

内部内容片段

要使自定义代码段出现在 Inner content 列表中,请将其添加到 snippet_content 中:

/website_airproof/views/snippets/snippets.xml
<template id="snippets" inherit_id="website.snippets" name="Airproof - Snippets">
   <!-- Add the custom snippet to the group -->
   <xpath expr="//snippets[@id='snippet_content']/*[1]" position="before">
      <t t-snippet="website_airproof.s_airproof_snippet"
         string="Custom snippet"
         t-thumbnail="/website_airproof/static/src/img/wbuilder/s_airproof_snippet.svg" />
   </xpath>
</template>
内部内容选择器

要制作自定义代码段“内部内容”(可放入另一个构建块中),请将其选择器添加到 so_content_addition_selector 资源,其中包含现有内部内容构建块的所有选择器。

/website_airproof/static/src/website_builder/airproof_snippet_option_plugin.js
export class AirproofSnippetOptionPlugin extends Plugin {
   static id = "airproofSnippetOption";
   resources = {
      so_content_addition_selector: [".s_airproof_snippet"],
   };
}

重要

选项

选项允许用户使用网站生成器编辑代码片段的外观和行为。选项是用 JavaScript 定义并使用 XML 模板呈现的 OWL 组件。每个选项都通过构建器插件注册并加载到编辑器资产中。

注解

将 JavaScript 和 XML 文件添加到模块中的 website.website_builder_assets 包中。

组件和模板

定义选项组件并将其注册到构建器插件中。

/website_airproof/static/src/website_builder/airproof_snippet_option_plugin.js
import { BaseOptionComponent } from "@html_builder/core/utils";
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";

export class AirproofSnippetOption extends BaseOptionComponent {
   static template = "website_airproof.AirproofSnippetOption";
   static selector = ".s_airproof_snippet";
   static applyTo = ":scope > .row";
}

export class AirproofSnippetOptionPlugin extends Plugin {
   static id = "airproofSnippetOption";
   resources = {
      builder_options: [AirproofSnippetOption],
   };
}

registry.category("website-plugins").add(
   AirproofSnippetOptionPlugin.id,
   AirproofSnippetOptionPlugin
);

然后定义在选项面板中呈现的 XML 模板。

/website_airproof/static/src/website_builder/airproof_snippet_option.xml
<templates xml:space="preserve">
   <t t-name="website_airproof.AirproofSnippetOption">
      <BuilderRow label.translate="Layout">
         <BuilderSelect>
            <BuilderSelectItem classAction="''">Default</BuilderSelectItem>
            <BuilderSelectItem classAction="'s_airproof_snippet_portrait'">Portrait</BuilderSelectItem>
            <BuilderSelectItem classAction="'s_airproof_snippet_square'">Square</BuilderSelectItem>
            <BuilderSelectItem classAction="'s_airproof_snippet_landscape'">Landscape</BuilderSelectItem>
         </BuilderSelect>
      </BuilderRow>
      <BuilderRow label.translate="Space">
         <BuilderButtonGroup>
            <BuilderButton classAction="'mt-0'">1</BuilderButton>
            <BuilderButton classAction="'mt-3'">2</BuilderButton>
            <BuilderButton classAction="'mt-5'">3</BuilderButton>
         </BuilderButtonGroup>
      </BuilderRow>
   </t>
</templates>

选项逻辑

在 JavaScript 中定义 BaseOptionComponent 类的选项行为,并在构建器插件资源中注册模板使用的任何 BuilderAction

插件API

构建器插件通过 resources 对象注册选项组件、操作和编辑器挂钩。它们被添加到 website-plugins 注册表类别中,以便编辑器可以访问。插件实例在编辑器启动时创建,在编辑器关闭时销毁,它们在整个编辑器会话中都存在。

财产

目的

static dependencies

在安装程序运行之前声明所需的插件。

static shared

将共享方法公开给其他插件。

setup()

初始化插件状态。

资源

目的

builder_options

为选项面板注册 BaseOptionComponent 类。

builder_actions

注册选项模板引用的 BuilderAction 类。

dropzone_selector

定义代码片段删除规则(selectordropIndropNearexcludeexcludeNearParent)。

so_content_addition_selector

扩展内部内容选择器的列表。

处理程序

在插件上注册的编辑器生命周期挂钩。

on_snippet_dropped_handlers

在将代码片段拖放到 DOM 中并将其插入后调用。

on_cloned_handlers

在克隆元素并将其插入 DOM 后调用。

on_will_remove_handlers

在删除元素之前调用。

on_removed_handlers

删除元素后调用。

clean_for_save_handlers

在保存之前调用 DOM 的清理克隆。

before_save_handlers

在保存过程开始时调用。

after_save_handlers

保存过程完成后调用。

其他资料

Full resources list

基本选项组件 API

选项组件继承自 BaseOptionComponent 并定义静态元数据和可选组件行为。当当前选择与其选择器匹配时,它们会被实例化,当选择更改且不再匹配时,它们会被销毁,从而导致生命周期较短。

财产

描述

static template

OWL 模板名称呈现在选项面板中。

static selector

将选项绑定到元素的 CSS 选择器。

static exclude

要从匹配中排除的元素的 CSS 选择器。

static applyTo

针对匹配片段的子元素的 CSS 选择器。

static components

模板中使用的子构建器组件。

setup()

初始化组件状态。

装订

选择器

选项组件声明一个选择器属性来控制它们何时出现。

selector 将选项组件绑定到与 CSS 选择器(类、ID 等)匹配的元素。当选择匹配元素时会出现该选项。

export class AirproofSnippetOption extends BaseOptionComponent {
   static selector = "section, h1, .custom_class, #custom_id";
}

它可以与 excludeapplyTo 结合使用。

适用于

applyTo 允许选项应用于匹配选择器的子元素。

export class AirproofSnippetOption extends BaseOptionComponent {
   static selector = ".s_airproof_snippet";
   static applyTo = ".row";
}
排除

exclude 从匹配中删除特定选择器。

如果选择 <ul> 标签(没有 .navbar-nav 类),则会出现该选项
export class AirproofSnippetOption extends BaseOptionComponent {
   static selector = "ul";
   static exclude = ".navbar-nav";
}
dropzone_selector(dropIn)

dropIn 定义了代码片段可以放入的元素。

export class AirproofSnippetOptionPlugin extends Plugin {
   static id = "airproofSnippetOption";
   resources = {
      dropzone_selector: {
         selector: ".s_airproof_snippet",
         dropIn: ".x_custom_location",
      },
   };
}
dropzone_selector(dropNear)

dropNear 定义片段可以放置在其旁边的元素。

export class AirproofSnippetOptionPlugin extends Plugin {
   static id = "airproofSnippetOption";
   resources = {
      dropzone_selector: {
         selector: ".s_airproof_snippet_card",
         dropNear: ".card",
      },
   };
}

布局和字段

使用构建器组件来组成选项面板 UI。

<BuilderRow>

创建一个带标签的行来对选项字段进行分组。使用 label.translate 作为行标题,使用 level 缩进嵌套行。

<BuilderRow label.translate="My option">
   <BuilderSelect>...</BuilderSelect>
   <BuilderButtonGroup>...</BuilderButtonGroup>
</BuilderRow>

这种情况的完美示例是 Animation 行:

将不同的选项字段分组到同一行中。
<BuilderButton>

该标签在 <BuilderButtonGroup> 内部使用或单独使用。

<BuilderButtonGroup>
   <BuilderButton classAction="'mt-0'">1</BuilderButton>
   <BuilderButton classAction="'mt-3'">2</BuilderButton>
   <BuilderButton classAction="'mt-5'">3</BuilderButton>
</BuilderButtonGroup>

添加 classAction 以指示选择此选项时哪个类应用于目标元素。与任何 XML 节点一样,添加其他属性以改进样式和/或用户体验。

<BuilderButton
   icon="'fa-align-right'"
   title.translate="Align right"
   classAction="'ms-auto'" />
添加选项选项并使用一些图标设置它们的样式
<BuilderSelect>

将选项格式设置为下拉列表。

<BuilderSelect>
   <BuilderSelectItem classAction="''">Default</BuilderSelectItem>
   <BuilderSelectItem classAction="'s_layout_variant'">Variant</BuilderSelectItem>
</BuilderSelect>
添加下拉列表字段
<BuilderButtonGroup>

将选项格式设置为彼此相邻的按钮并处理选择状态。

<BuilderButtonGroup>...</BuilderButtonGroup>
添加一组按钮
<BuilderCheckbox>

将选项格式化为切换开关。

<BuilderCheckbox
   classAction="'s_airproof_snippet_tooltip'" />
添加一个拨动开关。
<BuilderRange>

将选项格式设置为滑块。

<BuilderRange> 可用于设置数值:

<BuilderRange
   action="'setSpeed'"
   min="0"
   max="10"
   step="1"
   displayRangeValue="true" />

它还可用于将每个步骤映射到 actionParam 中的条目:

<BuilderRange
   action="'setClassRange'"
   actionParam="['o_spc-none', 'o_spc-small', 'o_spc-medium', 'o_spc-big']"
   max="3" />
添加范围滑块。
<BuilderNumberInput><BuilderTextInput>

将选项格式设置为数字或文本字段。

unitsaveUnitstep 是可选的
<BuilderNumberInput
   styleAction="'animation-duration'"
   unit="'s'"
   saveUnit="'ms'"
   step="0.1" />
添加数字输入。

<BuilderNumberInput> 带有可选道具:

属性

描述

unit

显示预期的计量单位。

saveUnit

设置用户输入的值转换并保存的测量单位。

step

设置字段可以递增的数值。

<BuilderList>

在选项面板中渲染和编辑项目列表(添加、删除、重新排序)。对于预填充值、自定义选项或映射到对象列表的设置很有用。

具有两个字段的简单列表
<BuilderList
   action="'setPrefilledOptions'"
   addItemTitle.translate="Add"
   itemShape="{ value: 'number', description: 'text' }"
   default="{ value: '50', description: 'Add a description here' }"
   columnWidth="{ value: 'w-25' }"
   sortable="true" />

支柱

描述

itemShape

每列的字段类型。支持的类型:textnumberbooleanexclusive_boolean

default

新项目的默认值。键必须匹配 itemShape

records

可选的可用记录列表(JSON 列表)。设置后,添加按钮将变为下拉菜单。

defaultNewValue

创建新项目时注入的额外值(例如记录 ID)。

sortable

允许拖放重新排序(默认值:true)。

hiddenProperties

按名称隐藏特定列。

columnWidth

每列应用的 CSS 类(例如 w-25)。

forbidLastItemRemoval

防止移除最后剩余的项目。

<BuilderColorPicker>

将选项格式设置为可供选择的颜色/渐变。

<BuilderColorPicker
   action="'selectFilterColor'"
   defaultOpacity="50"
   enabledTabs="['custom', 'gradient']" />
添加颜色选择器。

属性

描述

enabledTabs

限制可用的选择器选项卡(例如 ['theme', 'gradient', 'custom'])。

defaultColor

未应用任何选择时显示的默认颜色。

defaultOpacity

选择器的默认 alpha 值。

行动

构建器组件触发 BuilderAction 类。使用速记操作道具或声明自定义操作并通过模板中的 action id 引用它们。

核心行动

核心操作可用作构建器组件上的简写 props。

动作/道具

描述

classAction

添加/删除目标元素上的 CSS 类。

styleAction

在目标元素上设置内联样式属性。

attributeAction

设置或删除 DOM 属性。

dataAttributeAction

设置或删除数据集键(不带 data- 前缀)。

setClassRange

根据所选范围值应用预定义列表中的一个类。

action + actionParam

调用在构建器插件中注册的自定义操作。

动作生命周期

BuilderAction 类可以实现构建器根据小部件调用的生命周期:

方法

描述

prepare

在使用组件之前准备异步数据。

load

预览操作时在 apply 之前加载数据。

apply

将操作应用于目标元素。

clean

当新选择取代操作时重置操作。

getValue

返回输入小部件的当前值。

isApplied

返回该操作对于可选择的小部件是否处于活动状态。

getPriority

当多个选项有效时,决定哪个可选项目获胜。

自定义操作

要创建自定义行为,请定义 BuilderAction 并将其注册到您的构建器插件中。

/website_airproof/static/src/website_builder/airproof_snippet_option_plugin.js
import { BuilderAction } from "@html_builder/core/builder_action";
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";

export class AirproofLayoutAction extends BuilderAction {
   static id = "airproofLayout";
   apply({ editingElement, params: { mainParam } }) {
      editingElement.classList.toggle("s_airproof_snippet_portrait", mainParam === "portrait");
      editingElement.classList.toggle("s_airproof_snippet_square", mainParam === "square");
   }
   isApplied({ editingElement, params: { mainParam } }) {
      return editingElement.classList.contains(`s_airproof_snippet_${mainParam}`);
   }
}

export class AirproofSnippetOptionPlugin extends Plugin {
   static id = "airproofSnippetOption";
   resources = {
      builder_actions: { AirproofLayoutAction },
   };
}

registry.category("website-plugins").add(
   AirproofSnippetOptionPlugin.id,
   AirproofSnippetOptionPlugin
);

最后,可以从 XML 模板调用自定义操作。

<t t-name="website_airproof.AirproofSnippetOption">
   <BuilderRow label.translate="Layout">
      <BuilderButtonGroup action="'airproofLayout'">
         <BuilderButton actionParam="'portrait'">Portrait</BuilderButton>
         <BuilderButton actionParam="'square'">Square</BuilderButton>
      </BuilderButtonGroup>
   </BuilderRow>
</t>

其他资料

动态内容模板

默认情况下,动态内容块具有网站生成器中可用的一系列模板选择。通过对模板 id 属性使用相同的命名约定,还可以将自定义模板自动添加到列表中。

调用模板

所选动态代码段将 <div class="dynamic_snippet_template"/> 占位符替换为基于 data-template-key 和自定义 CSS 类的正确模板:

<section
   data-snippet="s_blog_posts"
   data-name="Blog Posts"
   class="s_blog_post_airproof s_dynamic_snippet_blog_posts s_blog_posts_post_picture_size_default s_dynamic pt64 pb64 s_blog_post_card o_colored_level o_dynamic_snippet_loading"
   data-template-key="website_airproof.dynamic_filter_template_blog_post_airproof"
   data-custom-template-data="{
      blog_posts_post_author_active:true,
      blog_posts_post_teaser_active:true,
      blog_posts_post_date_active:true,
      blog_posts_post_category_active:true,
      blog_posts_post_new_active:true
   }"
   data-number-of-records="16"
   data-filter-by-blog-id="-1"
   data-filter-id="1"
   data-extra-classes="g-3"
   data-column-classes="col-12 col-sm-6 col-lg-4 col-xxl-3">
   <div class="s_dynamic_snippet_container container">
      <div class="row s_nb_column_fixed">
            <section class="s_dynamic_snippet_holder d-none px-4 placeholder-glow o_colored_level">
               <div class="row">
                  <span class="placeholder col-3 rounded" />
                  <span class="placeholder col-2 offset-7 rounded" />
                  <span class="placeholder mt-3 col-6 rounded" />
               </div>
               <div class="row mt-4">
                  <span class="placeholder col-12 rounded" style="height: 250px;" />
               </div>
            </section>
            <section class="s_dynamic_snippet_title oe_unremovable oe_unmovable flex-column flex-md-row mb-lg-0 pb-3 pb-md-0 s_col_no_resize o_colored_level d-flex justify-content-between">
               <div>
                  <h2 class="h3">Our latest content</h2>
                  <p class="lead">Check out what's new in our company!</p>
               </div>
               <div>
                  <a title="See All" href="/blog">
                     See all<span class="fa fa-long-arrow-right ms-2" />
                  </a>
               </div>
            </section>
            <section class="s_dynamic_snippet_content oe_unremovable oe_unmovable o_not_editable col s_col_no_resize o_colored_level">
               <div class="css_non_editable_mode_hidden">
                  <div class="missing_option_warning alert alert-info fade show d-none d-print-none rounded-0">
                        Your Dynamic Snippet will be displayed here... This message is displayed because you did not provide enough options to retrieve its content.<br/>
                  </div>
               </div>
               <div class="dynamic_snippet_template" />
            </section>
      </div>
   </div>
</section>

data-custom-template-data 可以接收模板渲染所需的任何自定义数据作为 JSON 字符串。它允许设置模板中使用的一些变量来显示/隐藏元素(作者、发布日期等)或传递内容呈现所需的任何特定信息。

示例

/website_airproof/views/snippets/s_snippet_name.xml
<template id="dynamic_filter_template_blog_post_airproof" name="...">
   <div t-foreach="records"
        t-as="data"
        class="s_blog_posts_post"
        data-extra-classes="g-3"
        data-column-classes="col-12 col-sm-6 col-lg-4 col-xxl-3">
      <t t-set="record" t-value="data['_record']" />
      <!-- Content -->
   </div>
</template>

属性

描述

ID

模板的 ID。必须以 dynamic_filter_template_blog_post_ 开头

姓名

人类可读的模板名称

数据额外类

在博客文章列的父级 .row 上添加了 CSS 类。

数据列类

CSS 类添加到博客明信片的父列上。

动态产品

动态产品片段在 Cards Design 下引入了一堆微样式选项。要设置这些选项之一,请将相关 CSS 类插入到 section 中。除了一些依赖 CSS 变量的异常之外,添加类会将选项设置为正确的值。

产品卡设计的可用选项
卡选项

以下是这些可用选项的非详尽列表:

选项

描述

CSS 类/值

Hover Effect

悬停时的 Background 颜色

o_wsale_products_opt_hover_background

悬停时 Background Zoom

o_wsale_products_opt_hover_background o_wsale_products_opt_hover_background_zoom

Gap

产品卡之间的间距(从 0 到 28 像素)

例如:style="--o-wsale-products-grid-gap: 16px;"

Roundness

产品卡的边框半径

o_wsale_products_opt_rounded_0

o_wsale_products_opt_rounded_1

o_wsale_products_opt_rounded_2

o_wsale_products_opt_rounded_3

o_wsale_products_opt_rounded_4

o_wsale_products_opt_rounded_5

Colors

应用 Theme 选项卡中定义的颜色组合

.o_wsale_products_opt_cc o_wsale_products_opt_cc1

o_wsale_products_opt_cc o_wsale_products_opt_cc2

o_wsale_products_opt_cc o_wsale_products_opt_cc3

o_wsale_products_opt_cc o_wsale_products_opt_cc4

o_wsale_products_opt_cc o_wsale_products_opt_cc5

卡预设

也可以选择 Preset,而不是单独设置。它有一个布局类(目录或列表)、一个特定的样式类和所有类选项(见上文)。此动态代码段被强制目录显示 (o_wsale_products_opt_layout_catalog) 和以下预设之一:

预设

CSS类

缩略图

o_wsale_products_opt_design_thumbs

薯片

o_wsale_products_opt_design_chips

o_wsale_products_opt_design_cards

网格

o_wsale_products_opt_design_grid