mcpField
T
theme-snippets

theme-snippets

github.com/ahmed-lakosha设计与 UI7663 次安装31 周前更新
代码仓库

关于 theme-snippets

这是一份 Odoo 网站片段开发参考,涵盖静态与数据驱动模板、可配置选项和版本差异,适合跨 Odoo 版本创建或定制片段的开发者。

主要功能

  1. 01静态片段模板目录
  2. 02动态片段的数据流
  3. 03片段选项元素与属性
  4. 04JavaScript 处理器和组件
  5. 05Odoo 14–19 版本差异

适用场景

  1. 01为落地页或常见问题选择片段
  2. 02在 Odoo 模块中注册自定义片段
  3. 03配置片段的可编辑控件
  4. 04构建数据驱动的产品展示

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ahmed-lakosha/odoo-plugins --skill theme-snippets

安装后在 Claude Code 中输入/theme-snippets确认已加载。

详细介绍

Odoo 网站片段参考

片段架构

STATIC SNIPPETS (81+ templates)    DYNAMIC SNIPPETS (data-driven)
├── Pre-built HTML                  ├── ir.filters (data source)
├── Drag & drop                     ├── website.snippet.filter (fetcher)
└── 6 categories                    └── Display templates (renderer)

              SNIPPET OPTIONS SYSTEM
              we-select | we-button | we-colorpicker | we-input
              data-selector | data-select-class | data-js

静态片段清单(81+ 个模板)

结构(14)
ID名称最适用场景
s_banner横幅落地页
s_cover封面页眉
s_text_image文本 - 图片功能
s_image_text图片 - 文本功能
s_title标题区块标题
s_text_block文本块内容
s_numbers数字成就
s_three_columns栏内容网格
s_features功能优势
s_masonry_block瀑布流图库
s_image_gallery图片库作品集
功能(11)
ID名称最适用场景
s_comparisons对比产品对比
s_company_team团队关于页面
s_call_to_action行动号召转化
s_references引用社会认同
s_accordion手风琴常见问题
s_features_grid功能网格优势
s_pricelist价格表产品
s_faq_collapse常见问题支持
s_tabs选项卡内容组织
动态内容(15)
ID名称最适用场景
s_google_mapGoogle 地图联系页面
s_website_form表单潜在客户收集
s_social_media社交媒体互动
s_dynamic_snippet动态内容数据展示
s_countdown倒计时活动
s_popup弹出窗口促销
s_newsletter_block新闻简报营销
内部内容(16)
ID名称最适用场景
s_card卡片项目
s_three_cards / s_four_cards卡片服务/功能
s_timeline时间线历史
s_process_steps步骤教程
s_quotes_carousel用户评价社会认同
s_blockquote引用块强调
大型菜单(9)
ID名称
s_mega_menu_multi_menus多列菜单
s_mega_menu_cards卡片式菜单
s_mega_menu_big_icons大图标菜单
s_mega_menu_thumbnails缩略图图库

创建自定义片段

Odoo 14-17:简单注册

<template id="s_my_snippet" name="My Snippet">
    <section class="s_my_snippet pt48 pb48 o_cc o_cc1">
        <div class="container">
            <div class="row">
                <div class="col-lg-12 text-center">
                    <h2>My Custom Snippet</h2>
                    <p>Content goes here...</p>
                </div>
            </div>
        </div>
    </section>
</template>


<template id="s_my_snippet_insert" inherit_id="website.snippets">
    <xpath expr="//div[@id='snippet_structure']//t[@t-snippet][last()]" position="after">
        <t t-snippet="my_module.s_my_snippet"
           t-thumbnail="/my_module/static/src/img/snippets/s_my_snippet.svg">
            <keywords>my, custom, snippet</keywords>
        </t>
    </xpath>
</template>
Odoo 18-19:使用片段组(必需)



<template id="snippet_group_custom" inherit_id="website.snippets">
    <xpath expr="//div[@id='snippet_groups']" position="inside">
        <t snippet-group="custom"
           t-snippet="website.s_snippet_group"
           string="Custom Snippets"/>
    </xpath>
</template>


<template id="s_my_snippet_insert" inherit_id="website.snippets">
    <xpath expr="//div[@id='snippet_structure']/*[1]" position="before">
        <t t-snippet="my_module.s_my_snippet"
           string="My Snippet"
           group="custom"
           t-thumbnail="/my_module/static/src/img/snippets/s_my_snippet.svg"/>
    </xpath>
</template>
面板类别
面板 ID类别XPath
snippet_structure结构//div[@id='snippet_structure']
snippet_media图库//div[@id='snippet_media']
snippet_feature功能//div[@id='snippet_feature']
snippet_dynamic动态内容//div[@id='snippet_dynamic']
snippet_inner_content内部内容//div[@id='snippet_inner_content']

片段选项系统

We-* 元素
元素用途关键属性
we-select下拉菜单data-name、data-dependencies
we-button切换data-select-class、data-toggle-class
we-colorpicker颜色选择器data-css-property
we-input文本/数字data-attribute-name、data-unit
we-range滑块data-min、data-max、data-step
we-checkbox切换data-select-class
数据属性
属性用途
data-selector目标 CSS 选择器
data-select-class切换 CSS 类
data-css-property要修改的 CSS 属性
data-jsJavaScript 处理程序类
data-dependencies条件可见性
data-no-preview禁用实时预览
完整选项示例
<template id="s_my_snippet_options" inherit_id="website.snippet_options">
    <xpath expr="." position="inside">
        <div data-js="MySnippetHandler"
             data-selector=".s_my_snippet"
             data-drop-in=".oe_structure">

            <we-select string="Layout" data-name="layout_opt">
                <we-button data-select-class="layout-grid">Grid</we-button>
                <we-button data-select-class="layout-list">List</we-button>
            </we-select>

            <we-colorpicker string="Background"
                            data-select-style="true"
                            data-css-property="background-color"/>

            <we-range string="Spacing"
                      data-select-style="true"
                      data-css-property="gap"
                      data-min="0" data-max="100" data-step="5" data-unit="px"/>
        </div>
    </xpath>
</template>
内置 JS 处理程序

BackgroundImage、BackgroundPosition、BackgroundToggler、ColoredLevelBackground、BackgroundShape、ImageTools、Carousel、DynamicSnippet


动态片段

架构
Data Source (ir.filters) → Filter (website.snippet.filter) → Display Template
创建动态片段

步骤 1:定义筛选器

<record id="dynamic_filter_my_items" model="website.snippet.filter">
    <field name="name">My Items</field>
    <field name="model_name">my.model</field>
    <field name="limit">12</field>
    <field name="filter_id" ref="ir_filter_my_items"/>
</record>

步骤 2:显示模板

<template id="dynamic_filter_template_my_model_card" name="Card">
    <t t-foreach="records" t-as="record">
        <div class="col-lg-4 mb-4">
            <div class="card h-100 shadow-sm">
                <img t-att-src="record.image_url" class="card-img-top"/>
                <div class="card-body">
                    <h5 class="card-title" t-esc="record.name"/>
                </div>
            </div>
        </div>
    </t>
</template>

步骤 3:动态片段

<template id="s_dynamic_my_items" name="Dynamic My Items">
    <section class="s_dynamic_snippet s_dynamic_my_items pt48 pb48"
             data-snippet="s_dynamic_my_items"
             data-filter-id="my_module.dynamic_filter_my_items"
             data-template-key="my_module.dynamic_filter_template_my_model_card"
             data-number-of-elements="6">
        <div class="container">
            <div class="dynamic_snippet_template row"/>
        </div>
    </section>
</template>
Product Dynamic Snippets (website_sale)

Filters: dynamic_filter_newest_products, dynamic_filter_recently_sold_products, dynamic_filter_recently_viewed_products

Display templates: card_style, centered, horizontal_card, mini, minimalist_*, banner


Snippet JavaScript

publicWidget for Snippets
/** @odoo-module **/
import publicWidget from "@web/legacy/js/public/public_widget";

publicWidget.registry.MySnippet = publicWidget.Widget.extend({
    selector: '.s_my_snippet',
    disabledInEditableMode: false,

    start: function () {
        if (!this.editableMode) {
            this._initializeAnimations();
        }
        return this._super(...arguments);
    },

    destroy: function () {
        $(window).off('.mySnippet');
        this._super(...arguments);
    },
});
Snippet Options Handler
/** @odoo-module **/
import options from "@web_editor/js/editor/snippets.options";

options.registry.MySnippetOption = options.Class.extend({
    selectDataAttribute: function(previewMode, widgetValue, params) {
        this._super(...arguments);
        if (params.attributeName === 'layout') {
            this._applyLayout(widgetValue);
        }
    },
});

Version Differences

FeatureOdoo 14-17Odoo 18-19
RegistrationSimple XPathGroups required
JavaScript@odoo-modulePlugin-based (19)
Bootstrap4.x (14-15) / 5.1.3 (16-17)5.1.3
Dynamic SnippetsBasicFull + Categories
Odoo 19 Plugin Pattern
import { Plugin } from "@html_editor/plugin";
import { registry } from "@web/core/registry";

export class MySnippetPlugin extends Plugin {
    static id = "mySnippet";
    resources = {
        builder_options: [{
            template: "my_module.MySnippetOption",
            selector: "section",
            applyTo: ".s_my_snippet",
        }],
    };
}
registry.category("website-plugins").add("mySnippet", MySnippetPlugin);

评论

支持 Markdown