构建块¶
构建块(也称为片段)是用户设计和布局页面的方式。它们是设计中的重要 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 下的 JavaScript 文件是交互:example 使用了 s_floating_blocks snippet 和基础的 Interaction 类。
演示页面
必须安装演示数据才能访问此页面:
https://your-database.com/website/demo/snippets
布局¶
用户可以使用 Website Builder 编辑片段。一些 Bootstrap 类非常重要,因为 它们会触发某些 Website Builder 选项 。
包装器¶
任何片段的标准主容器是一个 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>
属性 |
描述 |
|---|---|
类 |
此片段的唯一类名 |
data-name |
显示在右侧面板中作为片段的名称。如果未找到,则回退到 Block 。 |
data-snippet |
系统用来识别片段 |
系统会在拖放过程中根据模板名称自动添加 data-name 和 data-snippet 属性。
警告
当在主题页面中声明片段时,应特别添加这些属性。
警告
避免在一个 section 标签内添加另一个 section 标签:这将触发 Website Builder 的选项两次。您可以改用内部内容片段。
小技巧
使用标准片段编写静态页面内容时,有两种可能的方法:
- 使用 Website Builder 预构建自定义静态页面: 拖放片段,然后
将代码复制/粘贴到您的文件中并清理它。
- 直接编写所有代码: 但要注意与 Website Builder 的兼容性。它
需要某些类、名称、ID、数据等才能正常工作。一个好的做法是查找 Odoo 源文件中创建的标准代码片段。请注意,Website Builder 有时会在片段拖放到页面后为其添加类。
元素¶
我们可以通过使用特定的 CSS 类来启用或禁用一系列“功能”。
尺寸调整¶
任何直接从 .row 元素派生的大 Bootstrap 列(遵循 Bootstrap 结构)都会被 Website Builder 触发以使其可调整大小。
.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>
注解
可以为某个 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-* 类由 Website Builder 生成,用于编辑目的。
网格项目内边距¶
<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 )。
自定义片段¶
一些更具体的需求需要创建自定义片段。以下是创建自定义片段的方法:
模板¶
首先创建片段模板,然后将其添加到列表中并通过 Website Builder 提供使用。
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 属性。否则,Website Builder 将无法识别该片段,并且在数据库升级时可能会出现问题。此外,请记住,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>
属性 |
描述 |
|---|---|
片段分组 |
分组的 ID |
t-snippet |
继承的模板 ID |
字符串 |
显示给用户的分组名称 |
t-thumbnail |
分组缩略图的路径 |
1. 添加 Snippet¶
然后将自定义片段添加到包含同一级别所有现有片段的 <snippets id="snippet_structure"> 中。Website Builder 将通过读取 <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 |
要使用的片段模板 |
分组 |
添加片段的分组。 |
<关键词> |
用户在片段面板的搜索字段中输入的关键词 |
内部内容片段¶
要让自定义 snippet 出现在 内部内容 列表中,请将其添加到 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>
Inner content 选择器¶
要让自定义 snippet 成为“inner content”(可拖放到另一个 building block 中),请将其选择器添加到 so_content_addition_selector 资源中,该资源包含所有已有 inner content building block 的选择器。
/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属性,因为这种构建块会直接出现在 Website Builder 的右侧选项面板中。
选项¶
选项允许用户通过 Website Builder 编辑 snippet 的外观与行为。选项是 JavaScript 中定义的 OWL 部件,通过 XML 模板渲染。每个选项通过一个 builder 插件进行注册,并加载到编辑器资产中。
注解
在你的模块中,将 JavaScript 与 XML 文件添加到 website.website_builder_assets 资产包。
部件与模板¶
定义选项部件并通过 builder 插件进行注册。
/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 定义选项行为,并在 builder 插件资源中注册模板所使用的任何 BuilderAction。
插件 API¶
Builder 插件通过 resources 对象注册选项部件、动作和编辑器钩子。它们被添加到 website-plugins 注册表类别,以便编辑器访问。插件实例在编辑器启动时创建,在编辑器关闭时销毁,其生命周期贯穿整个编辑器会话。
房产 |
用途 |
|---|---|
|
在 setup 运行之前声明所需的插件。 |
|
向其他插件公开共享方法。 |
|
初始化插件状态。 |
资源 |
用途 |
|---|---|
|
为选项面板注册 |
|
注册选项模板引用的 |
|
定义 snippet 拖放规则( |
|
扩展 inner content 选择器列表。 |
处理器 |
在插件上注册的编辑器生命周期钩子。 |
|
在 snippet 被拖放并插入 DOM 之后调用。 |
|
在元素被克隆并插入 DOM 之后调用。 |
|
在元素被移除之前调用。 |
|
在元素被移除之后调用。 |
|
在保存前,于清理后的 DOM 克隆上调用。 |
|
在保存流程开始时调用。 |
|
在保存流程完成后调用。 |
另请参阅
BaseOptionComponent API¶
选项部件继承自 BaseOptionComponent,并定义静态元数据以及可选的部件行为。当当前选区与它们的选择器匹配时,它们被实例化;当选区变更且不再匹配时,它们被销毁,因此生命周期较短。
房产 |
描述 |
|---|---|
|
在选项面板中渲染的 OWL 模板名称。 |
|
将选项绑定到元素的 CSS 选择器。 |
|
从匹配中排除的元素的 CSS 选择器。 |
|
指向所匹配 snippet 子元素的 CSS 选择器。 |
|
在模板中使用的子 builder 部件。 |
|
初始化组件状态。 |
绑定¶
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 从匹配中排除指定的选择器。
<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",
},
};
}
布局与字段¶
使用 builder 组件来构建选项面板的用户界面。
<BuilderRow>¶
创建一个带标签的行以归组选项字段。使用 label.translate 作为行标题,并使用 level 对嵌套行进行缩进。
<BuilderRow label.translate="My option">
<BuilderSelect>...</BuilderSelect>
<BuilderButtonGroup>...</BuilderButtonGroup>
</BuilderRow>
这种情况的完美示例是 动画 行:
<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> and <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 值。 |
操作¶
Builder 组件会触发 BuilderAction 类。可使用简写形式的动作属性,也可声明自定义动作,并在模板中通过 action id 引用它们。
核心动作¶
核心动作可作为 builder 组件上的简写属性使用。
动作/属性 |
描述 |
|---|---|
|
在目标元素上添加或移除 CSS 类。 |
|
在目标元素上设置内联样式属性。 |
|
设置或移除 DOM 属性。 |
|
设置或移除 dataset 键(不含 |
|
根据选定的范围值,从预定义列表中应用一个类。 |
|
调用已在 builder 插件中注册的自定义动作。 |
动作生命周期¶
BuilderAction 类可实现一个生命周期,builder 会根据部件类型调用相应的阶段:
方法 |
描述 |
|---|---|
|
在使用某个组件之前准备异步数据。 |
|
在预览动作时,于 |
|
将该动作应用到目标元素上。 |
|
当新的选项取代它时重置该动作。 |
|
返回输入部件的当前值。 |
|
返回该动作对于可选择部件是否处于激活状态。 |
|
当多个条目同时有效时,决定哪个可选项获胜。 |
自定义动作¶
要创建自定义行为,请定义一个 BuilderAction 并将其注册到你的 builder 插件中。
/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>
另请参阅
动态内容模板¶
默认情况下,动态内容块在 Website Builder 中有一组可用的模板。通过使用与模板 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 可接收模板渲染所需的任何自定义数据,以 JavaScript 对象表示法(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。必须以 |
名称 |
模板的可读名称 |
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。必须以 |
名称 |
模板的可读名称 |
每张幻灯片显示的产品数量(桌面端) |
桌面端每张幻灯片显示的产品数量 |
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。必须以 |
名称 |
模板的可读名称 |
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 Class |
|---|---|
缩略图 |
|
芯片 |
|
卡片 |
|
网格 |
|