关于 canvas-page-definition
此 skill 用于为 Drupal Canvas 项目编写 JSON 页面规范,面向开发者说明页面结构、组件引用、格式限制和验证方法,并指出无头项目的适用条件。
主要功能
- 01以 JSON 规范定义页面
- 02设置路径、元素、属性和插槽
- 03使用已发现的组件类型
- 04遵循图像与实体引用格式
- 05检查项目类型和页面配置
- 06使用 Canvas CLI 验证页面
适用场景
- 01创建可在本地预览的 Canvas 页面
- 02准备通过 CLI 推送和拉取的页面规范
- 03使用 URL 路径链接页面
- 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。Headless 代码库支持页面规格,但只有在
canvas.config.json 中启用了 sync.pages 时才应创建页面规格;使用 Canvas Create
(@drupal-canvas/create)生成的项目默认禁用此功能,且不会附带 pages/
目录——页面是框架应用中的路由。如果不存在此类依赖,则这是一个 Canvas 渲染的 React 代码库:组件采用 React
(index.jsx/.tsx),本技能中的所有内容均适用。这是仅有的两种项目类型。
权威定义
Canvas 页面是存储在仓库配置的 pagesDir 中的 JSON 页面规格。
Workbench 使用这些文件进行本地页面预览,而 Canvas CLI 的
push/pull 工作流则使用它们在本地项目与 Drupal Canvas 之间同步页面。
页面规格应完整反映作者在 Drupal Canvas 中可以构建的内容。
最低要求(MUST)
每个 Canvas 页面都必须满足以下所有检查:
- 页面文件存在于配置的页面目录中(
canvas.config.json中的pagesDir;默认值为./pages) - 页面文件是一个 JSON 对象
- 页面包含非空的
title - 页面包含以
/开头且在项目内唯一的path - 页面包含至少有一个元素的
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。可以从已知的 Drupal URL(例如 /node/123)、包含实体 ID 的内容列表或导出中获取;如果任务要求选择真实实体,也可以查询网站的内容 API。如果无法确定正确的实体,请向用户询问实体 ID。不要将实体 UUID、路径别名、标题或已解析的预览对象用作 target_id。
{
"type": "js.article-card",
"props": {
"article": {
"target_id": 123
}
}
}
格式限制
页面规范格式仅支持已发现的组件元素及其 props 和 slots。
这意味着页面规范无法直接表示:
- 手写的 React 包装组件,例如
PageLayout - 原始 HTML 布局元素,例如
<div>或<section> - 由
className控制的间距或自定义包装组件样式 - 内联复制现有组件标记的代码
如果需要布局基元,请先查找现有组件。如果不存在,请先创建该组件,再在页面规范中使用。
验证
完成前,请验证所有编写的页面。
npx canvas validate