mcpField
B
b2c-page-designer

b2c-page-designer

github.com/salesforcecommercecloud開発5789 回インストール今日更新
リポジトリ

b2c-page-designer について

Salesforce B2C Commerce Page Designerのページタイプと再利用可能なコンポーネントタイプを開発するスキルです。ファイル構成、メタデータ、属性、レンダリング、問題の調査を扱い、バージョン固有の情報は公式ドキュメントで確認するよう案内します。

主な機能

  1. 01ページ・コンポーネントタイプの構成
  2. 02JSONメタデータとスクリプトのパターン
  3. 03属性と領域の設定
  4. 04ページとコンポーネントのレンダリング案内
  5. 05エディター表示やスキーマの問題調査
  6. 06バージョン固有ドキュメントの確認

活用シーン

  1. 01再利用可能なPage Designerコンポーネントの作成
  2. 02ページ領域とコンポーネント属性の定義
  3. 03エディターに表示されないコンポーネントの調査
  4. 04対象バージョンのAPIとスキーマ詳細の確認

MCP 対応

バージョン固有のPage Designerドキュメントの確認に、MCP経由の`docs_search`と`docs_read`を推奨します。MCPサーバーを提供するとは記載されていません。

インストール

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

$npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill b2c-page-designer

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

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evals/
trigger-evals.json
references/
ATTRIBUTE-TYPES.md
META-DEFINITIONS.md

詳細

ページデザイナースキル

このスキルでは、Salesforce B2C Commerce 向けのカスタム Page Designer ページタイプとコンポーネントタイプの作成方法を説明します。

対象範囲と根拠

このスキルでは、バージョンに依存しないパターン、JSON スキーマ構造、コード例を使用して、B2C Commerce Page Designer(dw.experience パッケージ)を扱います。ここに示す JSON スキーマと Script API のシグネチャは例示であり、プラットフォームのバージョンによって変わる場合があります。特定のフレームワークやバージョンに関する質問に回答する前、またはユーザーが実行するコードを出力する前に、docs_search/docs_read(MCP)または b2c docs search/b2c docs read(CLI)を使用してドキュメントを確認してください。ここで説明していない Script API メソッド、属性スキーマの要件、バージョン固有の動作については、B2C Commerce のドキュメントを正規の根拠としてください。

正規ドキュメント:

  • dw.experience.PageMgr - ページとリージョンのレンダリング
  • dw.experience.PageScriptContext - ページスクリプトのコンテキスト API
  • dw.experience.ComponentScriptContext - コンポーネントスクリプトのコンテキスト API
  • dw.experience.Page - ページオブジェクトのメソッド
  • dw.experience.Component - コンポーネントオブジェクトのメソッド
  • dw.experience.Region - リージョンオブジェクトのメソッド
  • dw.experience.image.Image - 画像属性タイプ
  • dw.experience - パッケージの概要

概要

Page Designer を使用すると、マーチャントはビジュアルエディターでコンテンツページを作成、管理できます。開発者は以下を作成します。

  1. ページタイプ - リージョンを含むページ構造を定義します
  2. コンポーネントタイプ - 属性を設定できる再利用可能なコンテンツブロックです

ファイル構造

Page Designer のファイルは、カートリッジの experience ディレクトリにあります。

/my-cartridge
    /cartridge
        /experience
            /pages
                homepage.json           # Page type meta definition
                homepage.js             # Page type script
            /components
                banner.json             # Component type meta definition
                banner.js               # Component type script
        /templates
            /default
                /experience
                    /pages
                        homepage.isml   # Page template
                    /components
                        banner.isml     # Component template

命名規則: .json ファイルと .js ファイルの名前は一致させる必要があります。ファイル名、および experience/pages または experience/components 配下のサブディレクトリ名には、英数字またはアンダースコアのみを使用してください。

サブフォルダー内のコンポーネントタイプ: コンポーネントのメタデータとスクリプトは、サブディレクトリ(例:experience/components/assets/)に配置できます。この場合、コンポーネントタイプ ID はドット区切りのパスになります:assets.hero_image_block。templates/default/ 配下のテンプレートパスはそのパスと一致させる必要があります(例:templates/default/experience/components/assets/hero_image_block.isml)。また、スクリプトではパスが一致するように Template('experience/components/assets/hero_image_block') を呼び出す必要があります。保存される ID は component.{component_type_id} です。長さは合計で 256 文字を超えてはなりません。

ページタイプ

メタ定義(pages/homepage.json)

JSON スキーマの例です。バージョン固有のページタイプスキーマ要件は、公式プラットフォームドキュメントで確認してください。

{
    "name": "Home Page",
    "description": "Landing page with hero and content regions",
    "region_definitions": [
        {
            "id": "hero",
            "name": "Hero Section",
            "max_components": 1
        },
        {
            "id": "content",
            "name": "Main Content"
        },
        {
            "id": "footer",
            "name": "Footer Section",
            "component_type_exclusions": [
                { "type_id": "video" }
            ]
        }
    ]
}
ページスクリプト(pages/homepage.js)
'use strict';

var Template = require('dw/util/Template');
var HashMap = require('dw/util/HashMap');
var PageRenderHelper = require('*/cartridge/experience/utilities/PageRenderHelper.js');

module.exports.render = function (context) {
    var model = new HashMap();
    var page = context.page;

    model.page = page;
    model.regions = PageRenderHelper.getRegionModelRegistry(page);

    return new Template('experience/pages/homepage').render(model).text;
};
ページテンプレート(templates/default/experience/pages/homepage.isml)

これは SFRA のリージョンモデルパターンに従っています。ページスクリプトは PageRenderHelper.getRegionModelRegistry(page) を使用して pdict.regions を構築し、各 RegionModel.render() 呼び出しは、SFRA のレンダリング設定を使用してプラットフォームの PageMgr.renderRegion() に処理を委譲します。

<isdecorate template="common/layout/page">
    <div class="homepage">
        <div class="hero-region">
            <isprint value="${pdict.regions.hero.render()}" encoding="off"/>
        </div>

        <div class="content-region">
            <isprint value="${pdict.regions.content.render()}" encoding="off"/>
        </div>

        <div class="footer-region">
            <isprint value="${pdict.regions.footer.render()}" encoding="off"/>
        </div>
    </div>
</isdecorate>

コンポーネントタイプ

メタ定義(components/banner.json)

JSON スキーマの例です。バージョン固有のコンポーネントタイプスキーマ要件は、公式プラットフォームドキュメントで確認してください。

{
    "name": "Banner",
    "description": "Promotional banner with image and CTA",
    "group": "content",
    "region_definitions": [],
    "attribute_definition_groups": [
        {
            "id": "image",
            "name": "Image Settings",
            "attribute_definitions": [
                {
                    "id": "image",
                    "name": "Banner Image",
                    "type": "image",
                    "required": true
                },
                {
                    "id": "alt",
                    "name": "Alt Text",
                    "type": "string",
                    "required": true
                }
            ]
        },
        {
            "id": "content",
            "name": "Content",
            "attribute_definitions": [
                {
                    "id": "headline",
                    "name": "Headline",
                    "type": "string",
                    "required": true
                },
                {
                    "id": "body",
                    "name": "Body Text",
                    "type": "markup"
                },
                {
                    "id": "ctaUrl",
                    "name": "CTA Link",
                    "type": "url"
                },
                {
                    "id": "ctaText",
                    "name": "CTA Button Text",
                    "type": "string"
                }
            ]
        },
        {
            "id": "layout",
            "name": "Layout Options",
            "attribute_definitions": [
                {
                    "id": "alignment",
                    "name": "Text Alignment",
                    "type": "enum",
                    "values": ["left", "center", "right"],
                    "default_value": "center"
                },
                {
                    "id": "fullWidth",
                    "name": "Full Width",
                    "type": "boolean",
                    "default_value": false
                }
            ]
        }
    ]
}

コンポーネントのメタデータ: 必ず region_definitions を含めてください。コンポーネントにネストされたリージョンがない場合(他のコンポーネント用のスロットがない場合)は [] を使用します。

コンポーネントスクリプト(components/banner.js)
'use strict';

var Template = require('dw/util/Template');
var HashMap = require('dw/util/HashMap');
var URLUtils = require('dw/web/URLUtils');

module.exports.render = function (context) {
    var model = new HashMap();
    var content = context.content;

    // Access merchant-configured attributes
    model.put('image', content.image);        // Image object
    model.put('alt', content.alt);            // String
    model.put('headline', content.headline);  // String
    model.put('body', content.body);          // Markup string
    model.put('ctaUrl', content.ctaUrl);      // URL object
    model.put('ctaText', content.ctaText);    // String
    model.put('alignment', content.alignment || 'center');
    model.put('fullWidth', content.fullWidth);

    return new Template('experience/components/banner').render(model).text;
};

テンプレートパス: Template(...) に渡すパスは、templates/default/ 配下のテンプレートパスと一致させる必要があります。コンポーネントがサブフォルダーにある場合(例:experience/components/assets/hero_image_block)、Template('experience/components/assets/hero_image_block') を使用し、ISML を templates/default/experience/components/assets/hero_image_block.isml に配置してください。

色の処理(文字列またはカラーピッカーオブジェクト): 属性が16進文字列またはカラーピッカーオブジェクト { color: "#hex" } のどちらにもなり得る場合、スクリプトが両方に対応できるよう、小さなヘルパーを使用してください。

function getColor(colorAttr) {
    if (!colorAttr) return '';
    if (typeof colorAttr === 'string' && colorAttr.trim()) return colorAttr.trim();
    if (colorAttr.color) return colorAttr.color;
    return '';
}
コンポーネントテンプレート(templates/experience/components/banner.isml)
<div class="banner ${pdict.fullWidth ? 'banner--full-width' : ''}"
     style="text-align: ${pdict.alignment}">
    <isif condition="${pdict.image}">
        <img src="${pdict.image.file.absURL}"
             alt="${pdict.alt}"
             class="banner__image"/>
    </isif>

    <div class="banner__content">
        <h2 class="banner__headline">${pdict.headline}</h2>

        <isif condition="${pdict.body}">
            <div class="banner__body">
                <isprint value="${pdict.body}" encoding="off"/>
            </div>
        </isif>

        <isif condition="${pdict.ctaUrl && pdict.ctaText}">
            <a href="${pdict.ctaUrl}" class="banner__cta btn btn-primary">
                ${pdict.ctaText}
            </a>
        </isif>
    </div>
</div>

属性の型

属性スキーマの例です。バージョンごとの attribute_definition 構文については、公式プラットフォームドキュメントで確認してください。

型説明戻り値
stringテキスト入力文字列
text複数行テキスト文字列
markupリッチテキストエディターマークアップ文字列(encoding="off" を使用)
booleanチェックボックスブール値
integer数値入力整数
enum単一選択ドロップダウン文字列または整数(値によって異なります)
image画像選択file.absURL を持つ画像オブジェクト
fileファイル選択ファイルオブジェクト
urlURL 選択URL 文字列
categoryカテゴリー選択カテゴリーオブジェクト
product商品選択商品オブジェクト
pageページ選択ページオブジェクト
customJSON オブジェクトまたはカスタムエディターオブジェクト(またはエディター固有の値)

Enum — コンポーネントの表示に関する重要事項: values には文字列配列を使用してください。例:"values": ["left", "center", "right"]。{ "value": "x", "display_value": "X" } のようなオブジェクトは使用しないでください。この形式ではコンポーネントタイプが拒否され、Page Designer のコンポーネント一覧に表示されないことがあります。Enum 属性は、値が文字列の場合は文字列を、数値の場合は整数を返します。

カスタムエディターと色: editor_definition.type: "styling.colorPicker" などを指定した type: "custom" を使用するには、そのエディターを提供するカートリッジが Business Manager サイトのカートリッジパスに必要です。エディターにコンポーネントが表示されない場合は、色属性に type: "string" を使用してください(マーチャントが16進数の色コードを入力します)。スクリプトでは両方に対応し、文字列、または { color: "#hex" } のようなオブジェクトを受け入れるようにしてください(文字列を返す簡単な getColor(attr) ヘルパーなどを使用します)。

default_value: ストアフロントのレンダリングにのみ使用されます。Page Designer のビジュアルエディターで事前選択された値として表示されることはありません。

リージョン定義

{
    "region_definitions": [
        {
            "id": "main",
            "name": "Main Content",
            "max_components": 10,
            "component_type_exclusions": [
                { "type_id": "heavy-component" }
            ],
            "component_type_inclusions": [
                { "type_id": "text-block" },
                { "type_id": "image-block" }
            ]
        }
    ]
}
プロパティ説明
id一意のリージョン識別子
nameエディターでの表示名
max_componentsコンポーネントの最大数(任意)
component_type_exclusions使用不可のコンポーネント
component_type_inclusionsこれらのコンポーネントのみ使用可能

ページのレンダリング

コントローラー内
var PageMgr = require('dw/experience/PageMgr');

server.get('Show', function (req, res, next) {
    var page = PageMgr.getPage(req.querystring.cid);

    if (page && page.isVisible()) {
        res.page(page.ID);
    } else {
        res.setStatusCode(404);
        res.render('error/notfound');
    }
    next();
});
ISML 内
<isscript>
    var PageMgr = require('dw/experience/PageMgr');
    var page = PageMgr.getPage('homepage-id');
</isscript>

<isif condition="${page && page.isVisible()}">
    <isprint value="${PageMgr.renderPage(page.ID)}" encoding="off"/>
</isif>

コンポーネントグループ

エディターのサイドバーでコンポーネントを整理します。

{
    "name": "Product Card",
    "group": "products"
}

一般的なグループ:content、products、navigation、layout、media

Page Designer にコンポーネントが表示されない場合

  1. Enum: すべての enum 属性で、value/display_value を持つオブジェクトではなく、"values": ["a", "b"](文字列配列)を使用していることを確認してください。
  2. カスタムエディター: 問題のある属性の type: "custom"(色選択など)を type: "string" に置き換えて再デプロイしてください。その後コンポーネントが表示される場合、カスタムエディターまたは BM カートリッジパスに問題がある可能性があります。
  3. 命名: ファイル名とサブディレクトリ名には、英数字またはアンダースコアのみを使用してください。
  4. region_definitions: コンポーネントのメタデータには region_definitions を含めてください(ネストされたリージョンがない場合は [] を使用します)。
  5. テンプレートパス: スクリプト内の Template('...') パスが、templates/default/ 以下のテンプレートパスと一致している必要があります(experience/components/assets/... などのサブフォルダーも含みます)。
  6. ログ: Business Manager で Administration > Site Development > Development Setup を開き、Page Designer を開いたときに、コンポーネントタイプ ID に関連するスクリプトまたはメタデータのエラーログを確認してください。
  7. コードバージョン: カートリッジを正しいコードバージョンにデプロイしてください。非本番環境ではメタデータが数秒間キャッシュされることがあります。コードバージョンを切り替えるか、しばらく待ってみてください。

ベストプラクティス

  1. レンダリングには dw.util.Template を使用してください(dw.template.ISML は使用しないでください)。
  2. コンポーネントは自己完結させてください。コンポーネント間の依存関係は避けてください。
  3. オプションの属性にはデフォルト値を設定してください(レンダリングには適用されますが、エディターで事前選択された状態では表示されません)。
  4. 関連する属性は attribute_definition_groups でグループ化してください。
  5. 意味のある ID を使用してください。プログラムから使用されます。
  6. マーチャントがコンテンツを作成した後は、タイプ ID や属性タイプを変更しないでください(保存済みデータとの不整合が生じます)。必要に応じて、新しいコンポーネントタイプを追加し、古いタイプは非推奨にしてください。
  7. 列挙型には文字列配列を、色には文字列を優先して使用してください。ただし、BM カートリッジのパスとカスタムエディターを管理している場合は除きます。

詳細リファレンス

属性の包括的なドキュメントについては、以下を参照してください。

コメント