b2c-page-designer について
Salesforce B2C Commerce Page Designerのページタイプと再利用可能なコンポーネントタイプを開発するスキルです。ファイル構成、メタデータ、属性、レンダリング、問題の調査を扱い、バージョン固有の情報は公式ドキュメントで確認するよう案内します。
主な機能
- 01ページ・コンポーネントタイプの構成
- 02JSONメタデータとスクリプトのパターン
- 03属性と領域の設定
- 04ページとコンポーネントのレンダリング案内
- 05エディター表示やスキーマの問題調査
- 06バージョン固有ドキュメントの確認
活用シーン
- 01再利用可能なPage Designerコンポーネントの作成
- 02ページ領域とコンポーネント属性の定義
- 03エディターに表示されないコンポーネントの調査
- 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.jsonreferences/ATTRIBUTE-TYPES.mdMETA-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- ページスクリプトのコンテキスト APIdw.experience.ComponentScriptContext- コンポーネントスクリプトのコンテキスト APIdw.experience.Page- ページオブジェクトのメソッドdw.experience.Component- コンポーネントオブジェクトのメソッドdw.experience.Region- リージョンオブジェクトのメソッドdw.experience.image.Image- 画像属性タイプdw.experience- パッケージの概要
概要
Page Designer を使用すると、マーチャントはビジュアルエディターでコンテンツページを作成、管理できます。開発者は以下を作成します。
- ページタイプ - リージョンを含むページ構造を定義します
- コンポーネントタイプ - 属性を設定できる再利用可能なコンテンツブロックです
ファイル構造
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 | ファイル選択 | ファイルオブジェクト |
url | URL 選択 | URL 文字列 |
category | カテゴリー選択 | カテゴリーオブジェクト |
product | 商品選択 | 商品オブジェクト |
page | ページ選択 | ページオブジェクト |
custom | JSON オブジェクトまたはカスタムエディター | オブジェクト(またはエディター固有の値) |
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 にコンポーネントが表示されない場合
- Enum: すべての
enum属性で、value/display_valueを持つオブジェクトではなく、"values": ["a", "b"](文字列配列)を使用していることを確認してください。 - カスタムエディター: 問題のある属性の
type: "custom"(色選択など)をtype: "string"に置き換えて再デプロイしてください。その後コンポーネントが表示される場合、カスタムエディターまたは BM カートリッジパスに問題がある可能性があります。 - 命名: ファイル名とサブディレクトリ名には、英数字またはアンダースコアのみを使用してください。
- region_definitions: コンポーネントのメタデータには
region_definitionsを含めてください(ネストされたリージョンがない場合は[]を使用します)。 - テンプレートパス: スクリプト内の
Template('...')パスが、templates/default/以下のテンプレートパスと一致している必要があります(experience/components/assets/...などのサブフォルダーも含みます)。 - ログ: Business Manager で Administration > Site Development > Development Setup を開き、Page Designer を開いたときに、コンポーネントタイプ ID に関連するスクリプトまたはメタデータのエラーログを確認してください。
- コードバージョン: カートリッジを正しいコードバージョンにデプロイしてください。非本番環境ではメタデータが数秒間キャッシュされることがあります。コードバージョンを切り替えるか、しばらく待ってみてください。
ベストプラクティス
- レンダリングには
dw.util.Templateを使用してください(dw.template.ISMLは使用しないでください)。 - コンポーネントは自己完結させてください。コンポーネント間の依存関係は避けてください。
- オプションの属性にはデフォルト値を設定してください(レンダリングには適用されますが、エディターで事前選択された状態では表示されません)。
- 関連する属性は
attribute_definition_groupsでグループ化してください。 - 意味のある ID を使用してください。プログラムから使用されます。
- マーチャントがコンテンツを作成した後は、タイプ ID や属性タイプを変更しないでください(保存済みデータとの不整合が生じます)。必要に応じて、新しいコンポーネントタイプを追加し、古いタイプは非推奨にしてください。
- 列挙型には文字列配列を、色には文字列を優先して使用してください。ただし、BM カートリッジのパスとカスタムエディターを管理している場合は除きます。
詳細リファレンス
属性の包括的なドキュメントについては、以下を参照してください。
- メタ定義のリファレンス - JSON スキーマ全体
- 属性タイプのリファレンス - 使用例付きのすべての属性タイプ