关于 canai-prepare
用于生成可导入 CanAI 的静态 HTML 页面的 skill,面向需要制作可移植、自包含页面且不使用前端框架或构建工具的 Agent,并按规范组织导航和元数据以供后续导入。
主要功能
- 01每页生成一个完整 HTML 文件
- 02使用 Tailwind CSS、原生 JS 或 Alpine.js
- 03遵循 Lucide 图标约定
- 04使用相对资源路径以便移植
- 05导航标记及 pages.json、menus.json
适用场景
- 01将设计稿转换为静态 HTML
- 02将 SPA 路由转换为互相链接的 HTML 页面
- 03准备可导入 CanAI 的页面
- 04创建可在 WordPress 外预览的可移植文件
MCP 相关
该 skill 生成供后续导入 CanAI 的静态 HTML,也可将输出交给 canai-mcp 导入;README 未说明其管理 MCP 服务或客户端。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ usewp/ canai --skill canai-prepare安装后在 Claude Code 中输入/canai-prepare确认已加载。
附带文件references/BOILERPLATE.mdreferences/STRUCTURE-NAVIGATION.md
详细介绍
CanAI Prepare — 单 HTML 静态页面
生成可供后续导入 CanAI 的推荐静态标记:每个页面对应一份完整 HTML 文档(不使用 React/Vue/构建工具)。样式仅使用 Tailwind CSS 实用类;交互使用 原生 JS 或 Alpine.js;图标使用 Lucide(data-lucide)。
假设 Agent 在用户自己的文件夹中运行(不一定是 WordPress 根目录)。此技能仅专注于生成兼容 CanAI、可直接集成的单 HTML 输出——不要求使用 WP-CLI、.env.wplocal,也不要求写入 wp-content/。
请参阅 references/BOILERPLATE.md,了解规范骨架、Alpine/Lucide 模式,以及 pages.json / menus.json 格式。请参阅 references/STRUCTURE-NAVIGATION.md,了解 canai-prepare 和 canai-mcp 共用的 Atomic Design 导航约定。
目的
- 输出保存到当前工作目录(或用户指定的输出路径)。文件使用相对资源路径,使项目文件夹自包含且便于移植——之后可复制到 WordPress 上传目录、在本地提供服务,或交给
**canai-mcp**导入。 - 文件采用 CanAI 格式:包含 Atomic Design 导航注释、语义区域,以及可无缝映射到后续 Twig +
_canai_css/_canai_js的类名。
技术栈(严格)
| 允许使用 | 说明 |
|---|---|
| 语义化 HTML5 | <header>、<nav>、<main>、<section>、<article>、<aside>、<footer> |
| Tailwind CSS | 仅限实用类;准备好的 HTML 中不得包含 <style> 块(CanAI 将 CSS 存储在 _canai_css 中) |
| 原生 JS | 在 <body> 结束处使用小型 IIFE 或 DOMContentLoaded 处理程序 |
| Alpine.js | 当状态化 UI 比手写 JS 更简单时使用(下拉菜单、标签页、折叠面板) |
| Lucide | <i data-lucide="icon-name" class="h-5 w-5"></i> |
| 禁止使用 |
|---|
React、Vue、Svelte、Angular、打包工具、JSX、.vue SFC |
| 在此技能中使用 Tailwind CLI/构建步骤(仅使用 Play CDN 类) |
| 除 Tailwind 实用类之外的大型 CSS 框架 |
库注入 — CanAI 会在网站上处理
启用后,CanAI 会通过 WordPress 钩子输出相同的库。在 WP Admin → CanAI → Settings 中启用(TailwindManager、LucideManager、AlpineManager、AssetManager):
| 静态预览文件模拟的内容 | CanAI 加载位置 |
|---|---|
<title>…</title> | **wp_head()** — WordPress 输出文档标题(页面/文章的 SEO 标题);如果主题/布局已通过 wp_head() 输出标题,请勿在 _canai_html 中重复写入字面量 <title> |
Tailwind Play CDN、Alpine、Lucide UMD 的 <script> 标签(位于 <head> 中的 WPCanAI-PREVIEW-LIBS 内) | **wp_head()** — 将主题/CanAI 流程会在 </head> 前输出的脚本加入队列/注入 |
<script>lucide.createIcons();</script>(位于 </body> 前的 WPCanAI-PREVIEW-LIBS 内) | **wp_footer()** — 页脚脚本(图标初始化等) |
请勿假设每个网站的开关设置都相同:告知用户按需启用 Load Tailwind、Lucide 和 Alpine(如果模板使用 x-*)。
准备好的 .html 文件仍包含这些脚本的仅用于预览版本,因此可以在 WordPress 之外的浏览器中打开该文件。请将它们包裹在:
...
导入 CanAI 时,请从粘贴到模板中的标记中移除预览代码块 — CanAI 会通过 **wp_head()**/**wp_footer()** 提供 Tailwind/Lucide/Alpine。页面专属 JS 保留在预览标记之外(映射到 _canai_js)。
布局映射 — 页眉/页脚与主要内容
在完整的静态 HTML 文件中,可以包含 <header> 和 <footer>,用于预览和 SPA 拆分。导入 CanAI 后,通常按以下方式拆分:
**<header>...</header>** → header 类型的模板组件(网站导航框架),通常是主 layout 模板使用的网站页眉组件。**<footer>...</footer>** → footer 类型的模板组件,通常是主 layout 使用的网站页脚组件。**<main>...</main>**(页面正文)→ 页面或特定类型模板的**_canai_html**(位于 layout 中的{{ page_content }}内)。
生成相互链接的单个 HTML 文件(工作流 B)时,为静态预览在多个文件中重复页眉/页脚没有问题;导入时,将共享区域提取一次,放入 **wpcanai_template('site-header')**/**wpcanai_template('site-footer')**(或项目实际使用的页眉/页脚 slug)中,并在每个页面模板中仅保留 <main>(以及布局专属区域)。
导航 — 两个菜单,均需标记
一个网站最多有两个菜单:
primary(页眉导航)和footer(页脚导航)。标记这两个菜单,保留其真实链接,绝不要编造第三个菜单名称(topnav、mobile、main、social)。导入后,它们会成为网站的两个 WordPress 菜单,CanAI 绝不会渲染硬编码导航。
- 页眉导航: `` 紧接在
<nav data-canai-menu="primary" aria-label="Primary">之前。 - 页脚导航: `` 紧接在
<nav data-canai-menu="footer" aria-label="Footer">之前。如果页脚链接分布在多个列中,请将所有列都放在同一个<nav>中。 - 在两个导航中都保留真实的
<a href>链接(href="about.html"),这样文件就能在浏览器中预览。这里不要编写 Twig 或菜单循环:canai-mcp会在导入时将这些链接替换为get_menu()循环。 - 移动端抽屉会重复显示主导航链接,因此也要将其标记为
data-canai-menu="primary"。面包屑和分页属于Navigation地标,不是菜单,不带data-canai-menu。 - 在
pages.json旁边编写menus.json,按顺序列出每个已标记导航中的链接:{ "primary": [ … ], "footer": [ … ] }。指向生成页面的项目格式为{ "title", "page" }(page是该页面在pages.json中的slug);其他链接的格式为{ "title", "url" },还可选填"target": "_blank"和"children": [ … ](最多 3 层)。这与wpcanai-write-menu的items结构完全一致。示例见 references/BOILERPLATE.md。 - 大型菜单也是菜单数据。 不可点击的列标题或下拉菜单触发项,应作为带有
children且不含page或url的项目;链接的单行简介放在"description"中,Lucide 图标名称放在"icon"中(名称与其data-lucide相同)。在 HTML 中保留面板的真实标记(标题、图标、简介、链接),并在menus.json中列出相同结构。缩略图在 HTML 中保留为相对路径的<img>,不添加"image":canai-mcp会在导入时将其 sideload,并添加附件 ID。
输出路径
默认情况下,写入当前工作目录下的 **./<project-slug>/**(或用户指定的路径)。无需 WordPress 根目录或 uploads 文件夹。
<project-slug>/
index.html
about.html
...
assets/
hero.webp
...
pages.json # optional; multi-page / SPA decomposition
menus.json # the primary / footer nav links (see Navigation)
**project-slug:**简短的 kebab-case 名称(例如landing-q2、shop-redesign)。**assets/:从设计稿复制或从 SPA 导出的二进制媒体文件;使用相对**路径引用(src="assets/photo.jpg")。- **跨页面链接:**使用相对路径(
href="about.html"),不要使用绝对域名。
工作流 A — 图片 / 设计稿 → HTML
- 接收截图、Figma 导出文件或其他参考图片。
- 推断布局:页眉、主视觉区、各个版块、页脚;字体大小层级;间距;颜色用途(映射到 Tailwind 调色板 + 仅在需要时通过小型内联脚本扩展
tailwind.config——优先使用标准工具类)。 - 在选择图片容器类之前,先运行下方的图片构图预检。
- 为用户要求的每个不同的完整页面设计输出一个
.html文件。 - 使用准确的 HTML 格式
标记可导航元素,例如、和。遵循 references/STRUCTURE-NAVIGATION.md 中的受控词汇表。 - 将提取的栅格资源保存到
assets/中,并使用相对路径引用。使用稳定的文件名;也可在项目文件夹中用简短的README.txt列出这些文件。
图片构图预检
在编写容器标记之前,对每张重要的栅格图像执行此流程。徽标、图标、装饰纹理以及使用 object-contain 渲染的图像无需进行主体裁切分析。
- 检查素材本身,而不只是参考页面。 使用可用的本地图像信息工具读取图像的原始宽度和高度,并使用主机的图像查看器检查像素。记录宽高比(
width / height)以及重要区域:人脸、完整身体、共同主体、手、产品、奖项,或图像中嵌入的文字。如果无法检查素材,请使用object-contain或接近源图的宽高比来保留图像,而不要猜测会造成破坏的裁切方式。 - 根据源图形状和设计用途选择容器。 优先使用响应式
aspect-*工具类,而不是较浅的固定h-*裁切:原图为纵向 →aspect-[4/5]、aspect-[3/4]或aspect-square;正方形 →aspect-square或aspect-[4/3];横向 →aspect-[16/9]、aspect-[3/2]或aspect-[4/3]。只有在检查确认安全区域在每个目标断点都能完整容纳时,纵向图片才可使用横向裁切。 - 使用
object-cover时设置视觉焦点。 以以下基准为起点,再根据实际图像调整:头像/单人肖像object-[center_30%](Y 轴约为 25–35%);坐姿双人照object-[center_58%](Y 轴为 55–60%);站立合照object-[center_20%];手持物品的主体object-[center_80%](Y 轴为 75–85%),且至少使用aspect-[3/4]或高度相当的宽高比。偏离中心的主体需要同时设置两个坐标,例如object-[80%_25%]。这些只是起点,不能替代检查。 - 验证响应式裁切效果。 在窄屏手机和宽屏桌面尺寸下预览。人脸、头部、共同主体以及与任务相关的物品必须保持可见,且不能紧贴边缘。如果构图确实需要,请使用断点专属的宽高比/焦点类;如果无法实现稳定的裁切效果,则使用更高的/与源图比例匹配的容器,或使用
object-contain。
示例:
<div class="aspect-[4/5] overflow-hidden rounded-2xl sm:aspect-[3/4]">
<img src="assets/founder.webp" alt="Founder holding the product" class="h-full w-full object-cover object-[center_80%]" width="1200" height="1600" loading="lazy">
</div>
工作流 B — SPA / PWA → 链接式静态 HTML 页面
- 发现路由:路由器配置(
react-router、Vue Router、Next.jsapp/等)、sitemap、导航链接或用户提供的列表。 - 对每个路由生成一个自包含的 HTML 文件(每个文件都重复包含页眉/页脚/导航;此技能中不使用局部模板)。
- 将客户端导航替换为生成文件之间的普通
**<a href="...">**链接。 - 将框架组件降级为语义化 HTML + Tailwind + Alpine/原生行为。
- 编写
**pages.json**— 包含{ "slug", "title", "file" }的数组,用于追踪。 - 根据标记的页眉和页脚导航生成
**menus.json**(参见 导航 — 两个已标记的菜单)。
CanAI 兼容性检查清单
- 导航注释使用精确的 `` 语法和受控词汇。
- 每个
<main>、<section>、<header>、<footer>、<nav>和<aside>前面都紧邻对应的必需类型标记。 - 页眉导航使用
+ `<nav data-canai-menu="primary">`,页脚导航使用+<nav data-canai-menu="footer">;不得使用其他data-canai-menu值;menus.json列出它们的链接。 - 正文内容中不得包含
<style>;除非无法避免,否则不得使用内联style=""(优先使用工具类)。 - 脚本:预览库放在
WPCanAI-PREVIEW-LIBS内;页面逻辑放在下方,位于这些标记之外。 - 图片:已完成构图预检;包含描述性
alt、原始width/height、响应式宽高比容器,以及首屏以下图片的loading="lazy"。 - Lucide:装饰性图标使用
aria-hidden="true";控件具有aria-label。 - 链接:使用易读的链接文本;真实导航应避免使用
href="#"。
交接给 CanAI
- 设置: 在 CanAI → Settings 中启用 Tailwind、Lucide 和 Alpine(如有使用),以便脚本像上文所述那样通过
**wp_head()**/**wp_footer()**加载。 - 文档标题: 设置 WordPress 页面/文章标题(以及 SEO 插件字段,如有使用);
**wp_head()**会在正式网站上输出<title>;如果布局已包含{{ wp_head() }},则从导入的模板片段中省略重复的<title>。 - 布局: 将页眉标记移入网站页眉组件模板;将页脚移入网站页脚组件;在主布局模板中调用它们(
{{ wpcanai_template('site-header') }}、{{ wpcanai_template('site-footer') }}——使用项目中的实际 slug)。 - 导入: 使用
**canai-mcp**(将 HTML 转换为 Twig,写入_canai_html/_canai_css/_canai_js)——遵循该技能的存储规则(例如,CanAI 正文不得使用post_content)。 - 将内容粘贴到模板时,移除
WPCanAI-PREVIEW-LIBS块(避免重复注入 CanAI 已经添加的内容)。 - 图片会在导入时转换为基于 ID 的辅助函数,而不是在此处转换。 准备好的
.html保留相对src="assets/…",这样文件夹就能在普通浏览器中预览。导入时,canai-mcp会将每个资源上传到媒体库,并将<img>重写为{{ image_attrs(id, 'src,alt') }}(其他位置则重写为{{ media_url(id, size) }}),并使用媒体 id——因此,请保持准备好的标记简洁且易于替换:每个资源使用一个<img>,填写描述性alt,已知时填写width/height,并且不要添加会与辅助函数输出冲突的内联style。 - 导入时,导航注释会一对一映射: `` 会变为
{# Type / Short Label #}。原样保留类型和标签;只替换分隔符。遵循 references/STRUCTURE-NAVIGATION.md,包括必需的地标映射,以确保wpcanai-scan通过检查,并让编辑器的 Structure 元框保持实用。 - 确保文案便于翻译。 在使用原生 i18n 的目标网站上,后续导入会将每个面向用户的句子转换为一个
{{ t('…') }}翻译源。在块级元素中将每个句子写成一个单元:句子内部可以有内联标签(<p>Get <strong>free shipping</strong> today.</p>会变成一个翻译源),且句子内部不得出现块级元素。这与图片 →image_attrs()和分区注释的交接方式一致。 - WooCommerce 页面——对于商店/购物车/结账页面,将购物车/结账区域输出为一个可导航的占位符,例如
,并将任何实现说明放在单独的注释中。后续处理(canai-mcp)会替换为wc_*Twig 辅助函数;此处不要接入辅助函数标记。 - 导入时,导航会变为 WordPress 菜单。
canai-mcp会使用wpcanai-write-menu写入menus.json(页面创建后,每个 key 调用一次),并将每个已标记的<nav data-canai-menu>中的链接替换为get_menu('primary')/get_menu('footer')循环。准备好的文件会保留实际链接;网站所有者之后可在 WordPress 中编辑菜单。
相关技能
**canai-mcp**— 用于配置的服务上的_canai_*的 MCP 工具。