构建块¶
构建块(也称为片段)是用户设计和布局页面的方式。它们是您设计中重要的 XML 元素。
构建块分为两种类型:
结构块:在视觉上用作“整行”,并划分为多个类别(介绍、列、内容、图像、人员 等)
内部内容块:用于其他构建块内部
在本章结束时,您将能够 创建自定义片段,并将它们添加到专用类别中。
文件结构¶
视图模板位于 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 文件是交互,例如 示例 使用的是 s_floating_blocks 片段和基类 Interaction。
演示页面
需要安装演示数据才能访问此页面:
https://your-database.com/website/demo/snippets
布局¶
用户可以使用网站构建器编辑片段。某些 Bootstrap 类很重要,因为 它们会触发某些网站构建器选项。
包装器¶
任何片段的标准主容器都是 section。任何 section 元素都可以像内容块一样编辑,您可以移动或复制它。
<section class="s_snippet_name" data-name="..." data-snippet="...">
<!-- Content -->
</section>
对于内部内容片段,可以使用任何其他 HTML 标签。
<div class="s_snippet_name" data-name="..." data-snippet="...">
<!-- Content -->
</div>
属性 |
说明 |
|---|---|
class |
此片段的唯一类名 |
data-name |
在右侧面板中显示为片段的名称。如果未找到,将回退为 区块。 |
data-snippet |
系统用于识别片段 |
系统会在拖放过程中根据模板名称自动添加 data-name 和 data-snippet 属性。
警告
在主题页面上声明片段时,应显式添加这些属性。
警告
避免在一个 section 标签内再添加 section 标签:这会重复触发网站构建器的选项。您可以改用内部内容片段。
小技巧
使用标准片段编写静态页面的内容,有两种可选方法:
- 使用网站构建器预先构建自定义静态页面: 拖放片段,然后
将代码复制/粘贴到您的文件中并进行清理。
- 直接编写全部代码: 但要注意与网站构建器的兼容性。它
需要特定的类、名称、id、data 等才能正常工作。一种良好的做法是在 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>
注解
可以在区块上设置视频背景。请参阅本文档的 媒体 章节。
文本高亮¶
文本高亮是 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 自定义属性 |
说明 |
|---|---|
|
SVG 边框的粗细 |
|
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>
网格项的尺寸和位置由 grid-area 定义,可以在 style 属性中连同 z-index 一起显式设置。
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 自定义属性 |
说明 |
|---|---|
|
垂直内边距(Y 轴) |
|
水平内边距(X 轴) |
兼容性系统¶
- 当片段具有
data-vcss、data-vjs和/或data-vxml属性时,说明它是更新后的 版本,而不是原始版本。
<section class="s_snippet_name" data-vcss="001" data-vxml="001" data-vjs="001">
<!-- Content -->
</section>
这些数据属性告知系统为该片段加载哪个文件版本(例如 001.js、002.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-name 和 data-snippet 属性。否则,网站构建器将无法识别该片段,并且在每次数据库升级时都可能出现问题。此外,请记住 name 属性会在选项面板的 区块 部分中显示为自定义片段的名称。
小技巧
尽可能使用 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>
属性 |
说明 |
|---|---|
snippet-group |
分组的 ID |
t-snippet |
继承的模板 ID |
string |
向用户显示的分组名称 |
t-thumbnail |
分组缩略图的路径 |
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-snippet |
要使用的片段模板 |
group |
片段所属的分组。 |
<keywords> |
用户在片段面板的搜索字段中输入的关键词 |
内部内容片段¶
要让自定义片段显示在 内部内容 列表中,请改为将其添加到 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"],
};
}
重要
不要忘记添加
t-thumbnail并移除group属性,因为此类构建块可直接在网站构建器右侧的选项面板中使用。
选项¶
选项允许用户使用网站构建器编辑片段的外观和行为。选项是用 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>
选项逻辑¶
在 BaseOptionComponent 类上用 JavaScript 定义选项行为,并将模板使用的任何 BuilderAction 注册到构建器插件的资源中。
插件 API¶
构建器插件通过 resources 对象注册选项组件、动作和编辑器钩子。它们被添加到 website-plugins 注册表类别中,以便编辑器能够访问。插件实例在编辑器启动时创建,在编辑器关闭时销毁,它们存在于整个编辑器会话期间。
属性 |
目的 |
|---|---|
|
在 setup 运行前声明所需的插件。 |
|
向其他插件暴露共享方法。 |
|
初始化插件状态。 |
资源 |
目的 |
|---|---|
|
为选项面板注册 |
|
注册选项模板引用的 |
|
定义网站片段的放置规则( |
|
扩展内部内容选择器列表。 |
处理函数 |
注册在插件上的编辑器生命周期钩子。 |
|
在网站片段被放置并插入 DOM 后调用。 |
|
在元素被克隆并插入 DOM 后调用。 |
|
在元素即将被移除前调用。 |
|
在元素被移除后调用。 |
|
在保存前对 DOM 的清理副本调用。 |
|
在保存过程开始时调用。 |
|
在保存过程完成后调用。 |
更多内容
BaseOptionComponent API 参考¶
选项组件继承自 BaseOptionComponent,并定义静态元数据和可选的组件行为。当当前选择与其选择器匹配时,它们被实例化;当选择发生变化且不再匹配时,它们被销毁,因此生命周期很短。
属性 |
说明 |
|---|---|
|
在选项面板中渲染的 OWL 模板名称。 |
|
将选项绑定到元素的 CSS 选择器。 |
|
要从匹配中排除的元素的 CSS 选择器。 |
|
指向匹配到的网站片段的子元素的 CSS 选择器。 |
|
模板中使用的子构建器组件。 |
|
初始化组件状态。 |
绑定¶
selector¶
选项组件声明一个 selector 属性,用于控制它们何时显示。
selector 将选项组件绑定到匹配 CSS 选择器(类、ID 等)的元素上。当选中匹配的元素时,该选项就会出现。
export class AirproofSnippetOption extends BaseOptionComponent {
static selector = "section, h1, .custom_class, #custom_id";
}
它可以与 exclude 或 applyTo 组合使用。
applyTo¶
applyTo 允许选项应用到匹配选择器的子元素上。
export class AirproofSnippetOption extends BaseOptionComponent {
static selector = ".s_airproof_snippet";
static applyTo = ".row";
}
exclude¶
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 行:
<BuilderSelect>¶
将选项格式化为下拉列表。
<BuilderSelect>
<BuilderSelectItem classAction="''">Default</BuilderSelectItem>
<BuilderSelectItem classAction="'s_layout_variant'">Variant</BuilderSelectItem>
</BuilderSelect>
<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>¶
将选项格式化为数字字段或文本字段。
unit、saveUnit 和 step 是可选的¶<BuilderNumberInput
styleAction="'animation-duration'"
unit="'s'"
saveUnit="'ms'"
step="0.1" />
<BuilderNumberInput> 带有可选属性:
属性 |
说明 |
|---|---|
|
显示预期的计量单位。 |
|
设置用户输入的值在转换并保存时所采用的计量单位。 |
|
设置该字段可递增的数值步长。 |
<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" />
属性 |
说明 |
|---|---|
|
每列的字段类型。支持的类型: |
|
新项目的默认值。键必须与 |
|
可用记录的可选列表(JSON 列表)。设置后,添加按钮会变成下拉菜单。 |
|
创建新项目时注入的额外值(例如记录 ID)。 |
|
允许拖放重新排序(默认值:true)。 |
|
按名称隐藏特定的列。 |
|
按列应用的 CSS 类(例如 |
|
阻止移除最后一个剩余项目。 |
<BuilderColorPicker>¶
将选项格式化为可供选择的颜色/渐变。
<BuilderColorPicker
action="'selectFilterColor'"
defaultOpacity="50"
enabledTabs="['custom', 'gradient']" />
属性 |
说明 |
|---|---|
|
限制可用的选择器选项卡(例如 |
|
未应用任何选择时显示的默认颜色。 |
|
选择器的默认 alpha 值。 |
操作¶
构建器组件会触发 BuilderAction 类。使用简写的动作属性,或声明自定义动作并在模板中通过 action id 引用它们。
核心动作¶
核心动作可作为构建器组件上的简写属性使用。
动作/属性 |
说明 |
|---|---|
|
在目标元素上添加或移除 CSS 类。 |
|
在目标元素上设置内联样式属性。 |
|
设置或移除 DOM 属性。 |
|
设置或移除数据集键(不含 |
|
根据所选范围值,从预定义列表中选择一个类应用。 |
|
调用在构建器插件中注册的自定义动作。 |
动作生命周期¶
BuilderAction 类可以实现生命周期,由构建器根据控件调用:
方法 |
说明 |
|---|---|
|
在组件使用前准备异步数据。 |
|
预览动作时,在 |
|
将动作应用到目标元素。 |
|
当新的选择取代当前动作时,重置该动作。 |
|
返回输入控件的当前值。 |
|
返回该动作对可选控件是否处于激活状态。 |
|
当多个可选项都有效时,决定哪一个胜出。 |
自定义动作¶
要创建自定义行为,请定义一个 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 属性使用相同的命名约定,也可以将自定义模板自动添加到该列表中。
调用模板¶
所选的动态片段会根据 data-template-key 和自定义 CSS 类,用正确的模板替换 <div class="dynamic_snippet_template"/> 占位符:
<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。必须以 |
name |
模板的易读名称 |
data-extra-classes |
添加在博客文章各列父级 |
data-column-classes |
添加在博客文章卡片父列上的 CSS 类。 |
/website_airproof/views/snippets/s_snippet_name.xml¶<template id="dynamic_filter_template_product_product_airproof" name="...">
<t t-foreach="records"
t-as="data"
data-number-of-elements="4"
data-number-of-elements-small-devices="1"
data-number-of-records="8">
<t t-set="record" t-value="data['_record']" />
<!-- Content -->
</t>
</template>
属性 |
说明 |
|---|---|
id |
模板的 ID。必须以 |
name |
模板的易读名称 |
data-number-of-elements |
桌面端每张幻灯片的产品数量 |
data-number-of-elements-small-devices |
移动端每张幻灯片的产品数量 |
data-number-of-records |
获取的产品总数 |
/website_airproof/views/snippets/s_snippet_name.xml¶<template id="dynamic_filter_template_event_event_airproof" name="...">
<t t-foreach="records"
t-as="data"
data-extra-classes="g-3"
data-column-classes="col-12 col-sm-6 col-lg-4 col-xxl-3"
data-number-of-records="16">
<t t-set="record" t-value="data['_record']._set_tz_context()" />
<!-- Content -->
</t>
</template>
属性 |
说明 |
|---|---|
id |
模板的 ID。必须以 |
name |
模板的易读名称 |
data-extra-classes |
添加在活动各列父级 |
data-column-classes |
添加在活动卡片父列上的 CSS 类。 |
data-number-of-records |
抓取到的活动总数 |
动态产品¶
动态产品片段在 卡片设计 下提供了一组微调样式选项。要设置其中某个选项,请将相关的 CSS 类插入 section。除了一些依赖 CSS 变量的例外情况,添加该类即可将选项设置为正确的值。
卡片选项¶
以下是这些可用选项的非详尽列表:
选项 |
说明 |
CSS 类 / 值 |
|---|---|---|
悬停效果 |
悬停时的 背景 颜色 |
|
悬停时的 背景缩放 |
|
|
间距 |
产品卡片之间的间距(0 到 28px) |
例如: |
圆角 |
产品卡片的边框圆角半径 |
|
|
||
|
||
|
||
|
||
|
||
颜色 |
应用 主题 选项卡中定义的颜色组合 |
|
|
||
|
||
|
||
|
选项 |
说明 |
CSS 类 |
|---|---|---|
对齐 |
常规:左对齐 |
无需类 |
居中:居中显示 |
|
|
标题样式 |
产品标题使用 链接颜色 |
无需类 |
产品标题使用 默认颜色 |
|
|
粗体 |
产品标题使用 粗体 字重 |
|
字体大小 |
产品标题使用 响应式 字体大小 |
无需类 |
产品标题使用 主题默认 字体大小 |
|
|
描述 |
显示产品描述 |
|
评分 |
显示产品评分 |
|
选项 |
说明 |
CSS 类 |
|---|---|---|
图像比例 |
默认 (1/1) |
无需类 |
横向 (4/3) |
|
|
水平 (6/5) |
|
|
宽屏 (16/9) |
|
|
竖版 (4/5) |
|
|
垂直 (2/3) |
|
|
自动裁剪 |
自动裁剪图像 |
|
悬停效果 |
无 |
无需类 |
放大 |
|
|
轻度放大 |
|
|
缩小 |
|
|
缩小(浅色) |
|
|
图像阴影 |
|
选项 |
说明 |
CSS 类 |
|---|---|---|
按钮 |
:显示 加入购物车 按钮 |
|
始终显示 内联 操作按钮 |
|
|
在 悬停时 显示操作按钮 |
|
|
样式 |
淡雅 |
|
推广 |
|
|
主题颜色 |
|
卡片预设¶
除了单独设置之外,也可以选择一个 预设。该预设包含一个布局类(Catalog 或 List)、一个特定的样式类以及所有类选项(见上文)。此动态代码片段被强制为目录显示(o_wsale_products_opt_layout_catalog),并采用以下预设之一:
预设 |
CSS 类 |
|---|---|
缩略图 |
|
标签片 |
|
卡片 |
|
网格 |
|