canvas-page-definition について
Drupal Canvasプロジェクト向けにJSONページ仕様を作成するスキルです。開発者向けにページ構造、コンポーネント参照、形式制約、検証方法を説明し、ヘッドレスプロジェクトでの適用条件も示します。
主な機能
- 01JSON仕様でページを定義
- 02パス、要素、プロパティ、スロットを設定
- 03検出済みコンポーネント型を使用
- 04画像とエンティティ参照の形式に準拠
- 05プロジェクト種別とページ設定を確認
- 06Canvas CLIでページを検証
活用シーン
- 01ローカルでプレビューできるCanvasページを作成
- 02CLIのpush・pull用ページ仕様を準備
- 03URLパスでページ間をリンク
- 04完了前にページ仕様を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ drupal-canvas/ skills --skill canvas-page-definitionインストール後、Claude Code で/canvas-page-definitionを入力して読み込まれたか確認します。
詳細
プロジェクトの種類
このスキルを適用する前に、package.json を確認し、@drupal-canvas/headless または @drupal-canvas/headless- で始まる依存関係があるか調べてください。該当する依存関係がある場合、これは Canvas Headless コードベースです。まず canvas-headless を読んでください。ヘッドレスコードベースでもページ仕様を使用できますが、canvas.config.json で sync.pages が有効になっている場合にのみ作成してください。Canvas Create(@drupal-canvas/create)で生成したプロジェクトでは、デフォルトで無効になっており、pages/ ディレクトリは含まれません。ページはフレームワークアプリ内のルートです。該当する依存関係がない場合、これは Canvas レンダリングの React コードベースです。コンポーネントは React(index.jsx/.tsx)であり、このスキルの内容がすべてそのまま適用されます。プロジェクトの種類はこの2つだけです。
正式な定義
Canvas ページとは、リポジトリで設定された pagesDir に保存される JSON ページ仕様です。
Workbench は、ローカルでのページプレビューにこれらのファイルを使用します。また、Canvas CLI の push/pull ワークフローでは、これらのファイルを使用してローカルプロジェクトと Drupal Canvas の間でページを同期します。
ページ仕様は、作成者が Drupal Canvas で構築できる内容を完全に反映する必要があります。
最低限の要件(必須)
すべての Canvas ページは、以下のチェックをすべて満たす必要があります。
- ページファイルが設定済みのページディレクトリに存在すること(
canvas.config.jsonのpagesDir。デフォルトは./pages) - ページファイルが JSON オブジェクトであること
- ページに空でない
titleが含まれていること - ページに
/で始まるpathが含まれ、プロジェクト内で一意であること - ページに少なくとも1つの要素を含む
elementsオブジェクトがあること elements内のすべての要素に、検出済みコンポーネントのtypeが含まれていることslotsの各エントリーが、同じファイル内で定義された要素 ID を参照していること
いずれかの項目が欠けている場合、そのページは Canvas で使用するには不完全です。
保存場所と命名規則
正式なローカルページ仕様は、設定済みのページディレクトリ(canvas.config.json の pagesDir)に作成してください。pagesDir が設定されていない場合、Workbench は最上位の pages/ ディレクトリをデフォルトで使用します。
- 各ページを
<pages-dir>/<page-name>.jsonに配置します - 設定済みのページディレクトリ直下にページファイルを置きます。ネストされたファイルは無視されます
- ページタイトルをファイル名として安全な形式にした、安定したわかりやすいファイル名を使用します
- 実際のページタイトルには、JSON ファイル内の人間が読みやすい
titleを使用します
例:
<pages-dir>/homepage.json<pages-dir>/about-us.json
設定済みの pagesDir 内のファイルを、Workbench でプレビューでき、CLI を介して Canvas と同期できるローカルページ定義の信頼できる情報源として扱ってください。
作成したページは、設定済みの pagesDir からプレビューでき、検証の準備が整っていなければ未完成です。
ページファイルの形式
各ページファイルは、次の項目を含む JSON オブジェクトである必要があります。
title:実際のページタイトルpath:ページの URL パス(例:/about)。/で始まり、プロジェクト内で一意である必要があります。他のページからこの値を使ってリンクします。elements:作成したページ要素のオブジェクト
ページファイルには、次の項目も含められます。
description:ページの短いプレーンテキストの概要。ページのメタデータ(一覧や SEO など)として表示されます。設定しない場合は空文字列にします。
elements の各エントリーには、次の項目が必要です。
type:検出済みコンポーネントのタイプ
各エントリーには、次の項目も含められます。
props:その要素のルートプロパティslots:スロット名と、同じファイル内の要素 ID の配列を対応付けるマップ
Workbench はページの構築時に elements の挿入順序を保持します。最上位のセクションは、表示したい順序で配置してください。
各要素には、card、heading、js.hero など、ローカルプロジェクト内で Workbench が検出した機械可読なコンポーネントタイプを使用してください。
ページ間のリンク
プロジェクト内の別のページにリンクするには、リンク先ページの path を参照してください。
例
{
"title": "About",
"path": "/about",
"description": "",
"elements": {
"hero": {
"type": "js.hero",
"props": {
"heading": "About us",
"text": "Learn how our team plans, builds, and ships Canvas experiences.",
"layout": "left_aligned"
}
},
"spacer-lg": {
"type": "js.spacer",
"props": {
"height": "large"
}
},
"body-section": {
"type": "js.section",
"props": {
"width": "normal"
},
"slots": {
"content": ["body-copy"]
}
},
"body-copy": {
"type": "js.text",
"props": {
"content": "<p>Canvas pages should use real component composition rather than custom page wrappers.</p>"
}
}
}
}
別のソース(エクスポートした Canvas ページなど)の ID を意図的に保持する場合を除き、安定したわかりやすい要素 ID を使用してください。
ページ内の画像プロパティ
コンポーネントのプロパティが component.yml で画像として定義されている場合、ページ JSON ではそのプロパティに単一の画像オブジェクトを渡す必要があります。コンポーネントのプロパティ名と完全に一致させ、props 内では Canvas の画像形式を使用してください。
{
"type": "js.card",
"props": {
"image": {
"src": "https://placehold.co/400x300/png",
"alt": "Card placeholder image",
"width": "400",
"height": "300"
},
"heading": "Featured card"
}
}
ページで作成時に指定できる画像ソースは次のとおりです。
- 外部の
http://またはhttps://URL data:image/...URL
ページ JSON ではローカルファイルパスを使用しないでください。ローカルファイルからの CLI メディアアップロードはサポートされていません。
ページメディアの照合またはページ同期によって width、height、_provenance などの解決済み画像データが追加された場合、画像ソースを意図的に変更するのでなければ、そのデータを保持してください。
ページ内のコンテンツエンティティ参照プロパティ
コンポーネントのプロパティが component.yml でコンテンツエンティティ参照として定義されている場合、ページ JSON ではそのプロパティに選択したエンティティの値を指定してください。ページ仕様には dataDependencies.entityFields やフィールドブラウザーの式を記述しないでください。これらはコンポーネントのメタデータに属します。
作成時のページ仕様では、選択したエンティティ参照の形式として target_id を使用してください。JSX が受け取る解決済みの実行時形式が不明な場合は、コンポーネントのメタデータがローカルに存在する状態で npx canvas agents-context cer-preview <component> を実行し、解決済みのプロパティキーとネストされた値を確認してください。
target_id は選択したエンティティの Drupal エンティティ ID です。/node/123 などの既知の Drupal URL、エンティティ ID を含むコンテンツ一覧またはエクスポート、あるいはタスクで実際のエンティティを選ぶ必要がある場合はサイトのコンテンツ API へのクエリから取得してください。正しいエンティティを特定できない場合は、ユーザーにエンティティ ID を確認してください。エンティティ UUID、パスエイリアス、タイトル、解決済みのプレビューオブジェクトを target_id として使用しないでください。
{
"type": "js.article-card",
"props": {
"article": {
"target_id": 123
}
}
}
形式上の制約
ページ仕様の形式でサポートされるのは、検出済みのコンポーネント要素と、それらの props および slots のみです。
つまり、ページ仕様では次のものを直接表現できません。
- 手書きの
PageLayoutなどの React ラッパー <div>や<section>などの生の HTML レイアウト要素classNameによる余白の指定やカスタムラッパーのスタイル設定- 既存コンポーネントのマークアップをインラインコードで重複して記述すること
レイアウトプリミティブが必要な場合は、まず既存のコンポーネントを探してください。該当するものがない場合は、ページ仕様で使用する前にコンポーネントとして作成してください。
検証
作成したページはすべて、作業を完了する前に検証してください。
npx canvas validate