🚀 Apostrophe代码生成器
Apostrophe代码生成器是一款由AI驱动的工具,借助Claude AI和MCP(模型上下文协议)架构,为Apostrophe CMS模块生成代码。它能有效提升开发效率,让开发者更轻松地创建各类模块。

🚀 快速开始
node --version
claude --version
./install.sh
npm install && cd mcp-server && npm install
npm start
就这么简单! 选择一个项目,选择模块类型,进行配置,然后生成代码。
✨ 主要特性
- 片段生成器:创建存储在数据库中的内容类型。
- 页面生成器:生成具有内容区域和片段关系的页面类型。
- 小部件生成器:创建具有关系模式的可重用UI组件。
- 捆绑包生成器:一次性生成完整的功能集(片段 + 页面 + 小部件)。
- 设计令牌提取:自动提取并使用项目的设计令牌生成SCSS。
- BEM方法:可选的遵循BEM命名约定的SCSS生成(实验性)。
- 自动注册:自动将生成的模块注册到项目的
modules.js中。
- SCSS集成:自动创建并导入SCSS文件。
- 生成历史记录:浏览和重用以前生成的模块。
⚠️ 重要提示
CSS/SCSS生成是实验性的。结果可能因项目复杂性和设计令牌可用性而异。在部署到生产环境之前,请始终审查生成的样式。
📦 安装指南
快速安装(推荐)
cd /path/to/apostrophe-code-generator
./install.sh
安装脚本将执行以下操作:
- 检查Node.js和npm。
- 安装主应用程序依赖项。
- 安装MCP服务器依赖项。
- 可选地配置Claude Code集成。
手动安装
如果你更喜欢手动安装:
cd /path/to/apostrophe-code-generator
npm install
cd mcp-server
npm install
cd ..
💻 使用示例
启动应用程序
npm start
npm run dev
服务器将在 http://localhost:3031 上启动。
使用Web界面
- 打开浏览器 并导航到
http://localhost:3031。
- 选择一个项目:从下拉列表中选择一个Apostrophe项目。项目会从父目录中自动发现。
- 选择模块类型:选择你要生成的内容:
- 片段:存储在数据库中的内容类型。
- 页面:具有内容区域的页面类型。
- 小部件:可重用的UI组件。
- 捆绑包:完整的功能集(片段 + 页面 + 小部件)。
- 配置选项:填写模块详细信息:
- 模块名称
- 描述
- 字段和关系
- 样式选项(BEM、设计令牌)
- 生成:点击“生成代码”,让AI创建你的模块。
- 保存到项目:审查生成的代码并直接保存到你的项目中。
生成历史记录
所有生成的模块都会保存到历史记录中。你可以:
- 查看以前生成的模块
- 使用修改后的设置重新生成
- 将代码复制到剪贴板
- 从历史记录中删除
🔧 技术细节
高级:直接Claude Code MCP集成
本节为可选内容。localhost:3031 上的Web UI是使用此工具的主要方式。此MCP集成仅适用于希望直接从Claude Code CLI调用生成器而不使用Web界面的高级用户。
为什么使用此功能?
如果你已经在Apostrophe项目的Claude Code会话中工作,你可以直接要求Claude Code使用生成器工具来生成模块,而无需切换到浏览器。
示例:在Claude Code中,你可以说:
"使用apostrophe-generator为my-project创建一个名为news-feed的小部件"
配置
- 找到你的Claude Code设置文件:
- Linux/macOS:
~/.claude/settings.json
- Windows:
%USERPROFILE%\.claude\settings.json
- 添加MCP服务器配置:
{
"mcpServers": {
"apostrophe-generator": {
"command": "node",
"args": ["/absolute/path/to/apostrophe-code-generator/mcp-server/index.js"],
"env": {},
"description": "Apostrophe CMS代码生成工具"
}
}
}
将 /absolute/path/to/ 替换为你实际的安装路径。
3. 重启Claude Code 以加载新的MCP服务器。
可用的MCP工具
配置完成后,Claude Code中可使用以下工具:
| 工具 |
描述 |
list_apostrophe_projects |
列出所有发现的Apostrophe项目 |
generate_piece |
生成一个片段模块 |
generate_page |
生成一个页面模块 |
generate_widget |
生成一个小部件模块 |
generate_bundle |
生成一个完整的捆绑包 |
save_generated_code |
将生成的代码保存到项目中 |
生成模块结构
片段模块
片段是存储在数据库中的内容类型(如文章、产品、团队成员)。
生成的文件:
modules/pieces/{piece-name}/
└── index.js # 带有字段的模式定义
无模板 - 片段仅为数据;它们通过片段页面或小部件显示。
index.js结构:
export default {
extend: '@apostrophecms/piece-type',
options: {
label: 'Piece Name',
pluralLabel: 'Piece Names',
seoFields: false,
openGraph: false
},
fields: {
add: {
description: { type: 'string', label: 'Description' },
featuredImage: {
type: 'area',
label: 'Featured Image',
options: {
widgets: { '@apostrophecms/image': {} }
}
}
},
group: {
basics: {
label: 'Basics',
fields: ['title', 'description', 'featuredImage']
}
}
}
};
页面模块
页面是可通过URL路由的内容,可以显示片段(片段页面)或独立内容。
生成的文件:
modules/pages/{page-name}/
├── index.js # 模式定义
└── views/
├── index.html # 列表视图(用于片段页面)
└── show.html # 详细视图(用于片段页面)
对于独立页面,仅生成 page.html 而不是index/show。
index.js结构:
export default {
extend: '@apostrophecms/piece-page-type',
options: {
label: 'Page Name',
pieceModuleName: 'piece-name'
},
fields: {
add: {
},
group: {
}
}
};
小部件模块
小部件是可重用的UI组件,可以放置在内容区域中。
生成的文件:
modules/widgets/{widget-name}-widget/
├── index.js # 模式定义
└── views/
└── widget.html # 小部件模板
注意:小部件文件夹名称始终以 -widget 后缀结尾。
index.js结构:
export default {
extend: '@apostrophecms/widget-type',
fields: {
add: {
heading: { type: 'string', label: 'Heading' },
content: {
type: 'area',
label: 'Content',
options: {
widgets: {
'@apostrophecms/rich-text': {},
'@apostrophecms/image': {}
}
}
}
},
group: {
basics: {
label: 'Basics',
fields: ['heading', 'content']
}
}
}
};
widget.html模板:
<div class="widget-name-widget" data-widget-name-widget>
<h2>{{ data.widget.heading }}</h2>
{% area data.widget, 'content' %}
</div>
捆绑包模块
捆绑包一次性生成一个完整的功能集:片段 + 片段页面 + 小部件。
生成的文件:
modules/
├── pieces/{name}/
│ └── index.js
├── pages/{name}-page/
│ ├── index.js
│ └── views/
│ ├── index.html
│ └── show.html
└── widgets/{name}-widget/
├── index.js
└── views/
└── widget.html
捆绑包关系:
- 小部件自动包含一个
_pieces 关系字段以引用片段。
- 页面被配置为片段类型的片段页面。
SCSS生成(可选)
当启用 BEM样式 时,会生成额外的SCSS文件。
生成的SCSS文件
modules/asset/ui/src/scss/
├── components/
│ └── _{widget-name}.scss # 用于小部件
└── pages/
└── _{page-name}.scss # 用于页面
SCSS特性
- BEM方法:块-元素-修饰符命名约定。
- 设计令牌集成:使用项目现有的设计令牌(颜色、间距、排版)。
- 自动导入:SCSS文件会自动导入到主样式表中。
示例生成的SCSS:
.news-widget {
padding: $spacing-lg;
background-color: $color-background;
&__heading {
font-size: $font-size-xl;
color: $color-text-primary;
margin-bottom: $spacing-md;
}
&__content {
line-height: $line-height-relaxed;
}
&__item {
border-bottom: 1px solid $color-border;
padding: $spacing-md 0;
&:last-child {
border-bottom: none;
}
}
}
设计令牌提取
生成器会自动扫描项目中的设计令牌,位置如下:
modules/asset/ui/src/scss/_settings.scss
modules/asset/ui/src/scss/_variables.scss
- 任何匹配
*variables* 或 *tokens* 模式的文件
提取的令牌类型:
- 颜色 (
$color-*)
- 间距 (
$spacing-*)
- 排版 (
$font-*, $line-height-*)
- 断点 (
$breakpoint-*)
自动注册
生成的模块会自动注册到项目的 modules.js 文件中。
添加的内容
module.exports = {
'news': {},
'news-page': {},
'news-widget': {},
};
SCSS导入
如果生成了SCSS,会在主SCSS文件中添加导入语句:
@import 'components/_news-widget';
历史记录存储
所有生成的模块都会保存到 history/ 文件夹中,以便参考和重用。
历史记录文件夹结构
history/
└── 2025-11-18_14-30-45_news-widget/
├── metadata.json
└── modules/
└── widgets/
└── news-widget/
├── index.js
└── views/
└── widget.html
元数据格式
{
"moduleName": "news-widget",
"moduleType": "widget",
"projectName": "my-apostrophe-project",
"fileCount": 2,
"fullDesign": false,
"description": "A widget to display latest news items",
"timestamp": "2025-11-18T14:30:45.123Z"
}
历史记录特性
- 查看:浏览以前生成的模块。
- 重新生成:使用以前的设置作为起点。
- 复制:直接将代码复制到剪贴板。
- 删除:从历史记录中删除条目(不影响保存的项目文件)。
API端点
Express服务器暴露以下端点:
| 端点 |
方法 |
描述 |
/api/projects |
GET |
列出发现的Apostrophe项目 |
/api/generate |
POST |
生成一个模块 |
/api/save |
POST |
将生成的文件保存到项目中 |
/api/delete |
POST |
从项目中删除保存的文件 |
/api/history |
GET |
列出生成历史记录 |
/api/history/:id |
GET |
获取特定的历史记录条目 |
/api/history/:id |
DELETE |
删除历史记录条目 |
生成请求格式
{
"projectId": "my-project",
"type": "widget",
"name": "news",
"label": "News Widget",
"description": "Display latest news with images and summaries",
"includeBemStyles": true,
"fullDesign": false
}
生成响应格式
{
"success": true,
"files": [
{
"path": "modules/widgets/news-widget/index.js",
"content": "export default { ... }"
},
{
"path": "modules/widgets/news-widget/views/widget.html",
"content": "<div class=\"news-widget\">...</div>"
}
],
"registrationNote": "Module registered in modules.js",
"historyId": "2025-11-18_14-30-45_news-widget"
}
字段类型参考
模块模式可用的字段类型:
| 类型 |
描述 |
示例 |
string |
单行文本 |
{ type: 'string', label: 'Title' } |
area |
富内容区域 |
{ type: 'area', options: { widgets: {...} } } |
boolean |
复选框(true/false) |
{ type: 'boolean', label: 'Featured' } |
select |
下拉菜单 |
{ type: 'select', choices: [...] } |
checkboxes |
多选 |
{ type: 'checkboxes', choices: [...] } |
relationship |
链接到其他片段 |
{ type: 'relationship', withType: 'article' } |
array |
重复字段组 |
{ type: 'array', fields: { add: {...} } } |
date |
日期选择器 |
{ type: 'date', label: 'Publish Date' } |
time |
时间选择器 |
{ type: 'time', label: 'Event Time' } |
url |
URL输入 |
{ type: 'url', label: 'Website' } |
email |
电子邮件输入 |
{ type: 'email', label: 'Contact Email' } |
integer |
整数 |
{ type: 'integer', label: 'Quantity' } |
float |
小数 |
{ type: 'float', label: 'Price' } |
slug |
URL安全字符串 |
{ type: 'slug', following: 'title' } |
color |
颜色选择器 |
{ type: 'color', label: 'Background Color' } |
range |
滑块输入 |
{ type: 'range', min: 0, max: 100 } |
attachment |
文件上传 |
{ type: 'attachment', label: 'Document' } |
保留字段名称
切勿使用这些名称 - 它们是Apostrophe保留的:
type, _id, slug, published, archived
trash, visibility, createdAt, updatedAt
metaType, aposMode, aposLocale
替代方案:
- 代替
type → 使用 category, kind, itemType
- 代替
status → 使用 currentStatus, statusLabel
项目结构
apostrophe-code-generator/
├── server/ # Express服务器
│ ├── index.js # 主服务器入口点
│ ├── mcp-client.js # 用于AI生成的MCP客户端
│ └── apostrophe-docs/ # Apostrophe文档和模式
├── mcp-server/ # 用于Claude Code的MCP服务器
│ ├── index.js # MCP服务器入口点
│ ├── generator.js # 代码生成逻辑
│ ├── design-token-parser.js # 设计令牌提取
│ ├── package.json # MCP服务器依赖项
│ └── mcp-config.json # 示例MCP配置
├── public/ # Web UI
│ ├── index.html # 主向导界面
│ ├── css/ # 样式表
│ └── js/ # 客户端JavaScript
├── docs/ # 文档
├── history/ # 生成的模块历史记录
├── install.sh # 安装脚本
├── package.json # 主要依赖项
└── README.md # 此文件
配置
服务器端口
默认端口是 3031。要更改它,请设置 PORT 环境变量:
PORT=8080 npm start
项目发现
默认情况下,该工具会在父目录中查找Apostrophe项目。此行为是自动的,无需配置。
故障排除
常见问题
"Cannot find module '@modelcontextprotocol/sdk'"
MCP服务器依赖项未安装。运行:
cd mcp-server
npm install
"No projects found"
确保你的Apostrophe项目在父目录中,并且包含一个带有 shortName 属性的 app.js 文件:
module.exports = require('apostrophe')({
shortName: 'my-project',
});
"Claude API timeout" 或生成失败
- 确保安装了Claude Code:
claude --version
- 确保配置了Claude Code:
claude configure
- 检查你的Anthropic API密钥是否有效
- 尝试更简单的模块描述
- 检查你的互联网连接
"MCP server failed"
- 检查Claude设置中的MCP服务器路径是否正确
- 确保所有依赖项都已安装
- 检查Node.js版本(需要 >= 18)
端口已在使用中
另一个应用程序正在使用端口3031。你可以:
- 停止其他应用程序
- 使用不同的端口:
PORT=3032 npm start
获取帮助
如果你遇到问题:
- 检查浏览器控制台以查看错误信息
- 检查终端以查看服务器端错误
- 确保满足所有先决条件
- 验证项目结构是否符合预期格式
架构
组件
- Express服务器 (
server/index.js)
- 提供Web UI
- 处理API请求
- 管理项目发现
- 与MCP服务器通信
- MCP服务器 (
mcp-server/index.js)
- 提供由AI驱动的代码生成
- 与Claude AI集成
- 为Claude Code集成暴露工具
- Web UI (
public/)
数据流
用户输入 → Express服务器 → MCP服务器 → Claude AI
↓
用户 ← Web UI ← Express服务器 ← 生成的代码
开发
在开发模式下运行
npm run dev
这将启动服务器,并在文件更改时自动重新加载。
构建Tailwind CSS
如果你修改了样式:
./tailwindcss-linux-x64 -i public/css/input.css -o public/css/styles.css --watch
贡献
欢迎贡献代码!请确保:
- 代码遵循现有模式
- 记录新功能
- 通过测试(如果适用)
Windows安装
install.sh 脚本适用于Linux/macOS。Windows用户应手动安装:
使用命令提示符
cd path\to\apostrophe-code-generator
:: 安装主依赖项
npm install
:: 安装MCP服务器依赖项
cd mcp-server
npm install
cd ..
:: 启动服务器
npm start
使用PowerShell
cd path\to\apostrophe-code-generator
npm install
cd mcp-server
npm install
cd ..
npm start
Windows先决条件
- Node.js:从 https://nodejs.org/ 下载(v18+)
- Claude Code:
npm install -g @anthropic-ai/claude-code
- 配置Claude:
claude configure
兼容性
Apostrophe CMS版本
| Apostrophe版本 |
支持情况 |
| 4.x (A4) |
✅ 是 |
| 3.x (A3) |
✅ 是 |
| 2.x (A2) |
❌ 否 |
| 此工具为 Apostrophe 3.x和4.x 生成代码。模块结构、字段类型和模板语法与A3和A4都兼容。 |
|
Node.js版本
| Node.js版本 |
支持情况 |
| 22.x |
✅ 是 |
| 20.x |
✅ 是 |
| 18.x |
✅ 是 |
| 16.x及以下 |
❌ 否 |
操作系统
| 操作系统 |
支持情况 |
| Linux |
✅ 是 |
| macOS |
✅ 是 |
| Windows 10/11 |
✅ 是 |
| WSL/WSL2 |
✅ 是 |
已知限制
SCSS生成(实验性)
- 当项目有明确定义的设计令牌时,SCSS生成效果最佳。
- 如果项目中不存在令牌,生成的SCSS可能包含未定义的变量。
- 在编译之前,请始终审查生成的SCSS。
- 复杂的布局可能需要手动调整。
AI生成
- 结果取决于描述的质量。
- 非常复杂的模块可能需要多次生成或手动编辑。
- 生成时间会有所不同(通常根据复杂性为10 - 60秒)。
- 偶尔的JSON解析错误可能需要重试。
项目发现
- 仅发现 父目录 中的项目。
- 项目必须有带有
shortName 属性的 app.js 文件。
- 符号链接的项目可能无法被发现。
捆绑包生成
- 捆绑包一次生成3个模块 - 这可能需要更长时间。
- 所有3个模块共享相同的基本名称。
- 无法自定义捆绑包内各个模块的名称。
FAQ
一般问题
问:我需要Anthropic API密钥吗?
答:是的。Claude Code需要从 https://console.anthropic.com/ 获取的API密钥。
问:使用这个工具需要多少钱?
答:工具本身是免费的。你通过Anthropic账户支付Claude API的使用费用。每次生成通常使用1,000 - 5,000个令牌。
问:我可以离线使用这个工具吗?
答:不可以。该工具需要互联网连接才能与Claude AI通信。
项目问题
问:为什么我的项目没有出现在下拉列表中?
答:请确保你的项目:
- 位于此工具的父目录中。
- 有一个
app.js 文件。
- 在app.js中包含
shortName: 'your-project'。
问:我可以更改项目发现的位置吗?
答:目前不可以。项目必须位于父目录中。未来版本可能会支持配置。
生成问题
问:生成的代码有错误。我该怎么办?
答:尝试:
- 简化你的描述。
- 再次生成(AI响应可能会有所不同)。
- 手动编辑生成的代码。
- 检查是否使用了保留字段名称。
问:我可以在保存之前编辑生成的代码吗?
答:目前在UI中不可以。你可以先生成、保存,然后在IDE中进行编辑。
问:我如何重新生成一个模块?
答:使用历史记录功能查看以前的生成记录,并使用修改后的设置重新生成。
样式问题
问:SCSS中有未定义的变量。为什么?
答:生成器使用项目的设计令牌。如果某个令牌不存在,变量将未定义。请用实际值替换或在项目中添加这些令牌。
问:我可以禁用SCSS生成吗?
答:可以。在配置模块时,取消选中“Include BEM Styles”。
卸载
要删除代码生成器:
rm -rf /path/to/apostrophe-code-generator
npm uninstall -g @anthropic-ai/claude-code
卸载此工具不会影响你Apostrophe项目中已生成的模块。
📄 许可证
本项目采用MIT许可证,详情请参阅LICENSE文件。
致谢
创建者:Andrei Mateas
所属团队:GLOOBUS A-Team
本项目基于Claude AI和MCP(模型上下文协议)构建。
变更日志
v1.0.0
- 初始版本发布
- 片段、页面、小部件和捆绑包生成器
- 设计令牌提取
- BEM SCSS生成(实验性)
- 生成历史记录
- Claude Code MCP集成