构建块

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

构建块分为两种类型:

  1. 结构块:在视觉上用作“整行”,并划分为多个类别(介绍、列、内容、图像、人员 等)

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

在本章结束时,您将能够 创建自定义片段,并将它们添加到专用类别中。

文件结构

视图模板位于 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 自定义属性

说明

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

网格项的尺寸和位置由 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 自定义属性

说明

--grid-item-padding-y

垂直内边距(Y 轴)

--grid-item-padding-x

水平内边距(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"],
   };
}

重要

选项

选项允许用户使用网站构建器编辑片段的外观和行为。选项是用 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 注册表类别中,以便编辑器能够访问。插件实例在编辑器启动时创建,在编辑器关闭时销毁,它们存在于整个编辑器会话期间。

属性

目的

static dependencies

在 setup 运行前声明所需的插件。

static shared

向其他插件暴露共享方法。

setup()

初始化插件状态。

资源

目的

builder_options

为选项面板注册 BaseOptionComponent 类。

builder_actions

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

dropzone_selector

定义网站片段的放置规则(selector、dropIn、dropNear、exclude、excludeNearParent)。

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

在保存过程完成后调用。

更多内容

完整资源列表

BaseOptionComponent API 参考

选项组件继承自 BaseOptionComponent,并定义静态元数据和可选的组件行为。当当前选择与其选择器匹配时,它们被实例化;当选择发生变化且不再匹配时,它们被销毁,因此生命周期很短。

属性

说明

static template

在选项面板中渲染的 OWL 模板名称。

static selector

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

static exclude

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

static applyTo

指向匹配到的网站片段的子元素的 CSS 选择器。

static components

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

setup()

初始化组件状态。

绑定

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

将不同的选项字段分组到同一行中。
<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>

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

unit、saveUnit 和 step 是可选的
<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

每列的字段类型。支持的类型:text、number、boolean、exclusive_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 引用它们。

核心动作

核心动作可作为构建器组件上的简写属性使用。

动作/属性

说明

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 属性使用相同的命名约定,也可以将自定义模板自动添加到该列表中。

调用模板

所选的动态片段会根据 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。必须以 dynamic_filter_template_blog_post_ 开头

name

模板的易读名称

data-extra-classes

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

data-column-classes

添加在博客文章卡片父列上的 CSS 类。

动态产品

动态产品片段在 卡片设计 下提供了一组微调样式选项。要设置其中某个选项,请将相关的 CSS 类插入 section。除了一些依赖 CSS 变量的例外情况,添加该类即可将选项设置为正确的值。

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

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

选项

说明

CSS 类 / 值

悬停效果

悬停时的 背景 颜色

o_wsale_products_opt_hover_background

悬停时的 背景缩放

o_wsale_products_opt_hover_background o_wsale_products_opt_hover_background_zoom

间距

产品卡片之间的间距(0 到 28px)

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

圆角

产品卡片的边框圆角半径

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

颜色

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

.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

卡片预设

除了单独设置之外,也可以选择一个 预设。该预设包含一个布局类(Catalog 或 List)、一个特定的样式类以及所有类选项(见上文)。此动态代码片段被强制为目录显示(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