mcpField
T
theme-snippets

theme-snippets

github.com/ahmed-lakoshaデザイン・UI7663 回インストール31 週間前に更新
リポジトリ

theme-snippets について

Odoo のウェブサイトスニペットを開発するためのリファレンスです。静的・データ駆動型テンプレート、カスタマイズ項目、バージョン差を扱い、各バージョン向けにスニペットを作成・調整する開発者を対象としています。

主な機能

  1. 01静的スニペットテンプレート一覧
  2. 02動的スニペットのデータフロー
  3. 03スニペット設定要素と属性
  4. 04JavaScript ハンドラーとウィジェット
  5. 05Odoo 14~19 のバージョン差

活用シーン

  1. 01ランディングページや FAQ 用の選択
  2. 02Odoo モジュールへのカスタムスニペット登録
  3. 03編集可能なスニペットコントロールの設定
  4. 04データ駆動型の商品表示の構築

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/theme-snippetsを入力して読み込まれたか確認します。

詳細

Odoo Webサイトスニペットのリファレンス

スニペットのアーキテクチャ

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_actionCTAコンバージョン
s_references導入事例ソーシャルプルーフ
s_accordionアコーディオンFAQ
s_features_grid特徴グリッドメリット
s_pricelist価格表製品
s_faq_collapseFAQサポート
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-classCSS クラスの切り替え
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);

コメント