DocForge

面向插件和项目文档的开源文档 CMS。

v1.0.0 Cloudflare Workers WorkersD1R2Plugins

概览

DocForge 是一个运行在 Cloudflare Workers 上的轻量文档系统,用 D1 保存文档结构、翻译、媒体索引和插件配置,用 R2 保存媒体文件。

文档即数据

文档、章节、内容块、翻译和媒体都在 D1 中管理,后台编辑后立即生效。

多语言优先

内容使用 {{t:key}} 管理,插件也有独立 i18n,前台按当前语言渲染。

插件化前台

官方插件放在 Plugins/,私有插件放在 PrivatePlugins/,可扩展 CSS、JS、HTML 模板和自定义标签。

适合开源部署

README 说明标准部署流程,本地私有配置和私有插件默认不进入 git。

架构

项目保持简单的 Worker 架构:Hono 路由处理请求,模板函数输出 HTML,Drizzle schema 描述 D1 表结构。

前台文档和后台管理共用同一套内容模型,但入口分开:公开路由只读取启用文档,后台路由负责内容编辑、媒体、翻译、插件同步和统计。

src/
  routes/       HTTP routes for admin, public docs, APIs, media
  templates/    Server-rendered admin and public pages
  services/     auth, settings, i18n, official plugin runtime
  db/           Drizzle schema and D1 bindings
Plugins/        official publishable plugin manifests
PrivatePlugins/ local/private manifests ignored by git
migrations/     D1 schema migrations

内容模型

DocForge 的核心内容由四层组成:文档、章节、内容块和翻译。

  • 文档对应一个 slug,例如 /webuix 或 /docforge。
  • 章节支持顶级分组和子章节,前台会生成目录。
  • 内容块支持 HTML、代码、文本、卡片、列表、图片、视频和插件自定义类型。
  • 翻译表按 pluginId、key、locale 存储,前台自动按语言替换。
用途
plugins文档元信息、访问开关、首页展示开关、图标、标签和章节级 CSS/JS。
sections章节树、标题、slug、排序和父子关系。
content_blocks章节中的具体内容块,包含 HTML、代码、媒体和插件块。
translations文档翻译、系统翻译和插件运行时翻译。
extensions官方插件和私有插件同步后的运行配置。

后台工作流

后台围绕“文档 -> 章节 -> 内容块 -> 翻译/媒体”的流程设计,适合持续维护项目文档。

  1. 在文档管理中创建或编辑文档元信息。
  2. 使用章节编辑器维护目录、分组和子章节。
  3. 在编辑器中写 HTML/CSS/JS、代码块、媒体块或插件块。
  4. 翻译页扫描 {{t:key}} 并维护中英文内容。
  5. 发布前用预览页检查目录、样式、媒体和插件运行效果。
章节 CSS/JS 是文档级增强能力,适合控制当前文档的展示和交互;通用能力应沉淀为插件。

插件系统

插件 manifest 可以提供 HTML 模板、CSS、JS、标签 schema、配置和 i18n。官方插件通过 npm run plugins:sync 同步到 D1。

{
  "slug": "page-search",
  "name": "Page Search",
  "type": "system",
  "css": "...",
  "js": "...",
  "i18n": {
    "meta.name": { "zh": "页面搜索", "en": "Page Search" }
  }
}

媒体查看器和页面搜索现在作为官方内置插件维护在 Plugins/ 中,后续项目自带插件也可以按同样方式加入。

能力说明
css / js给前台文档注入样式和交互脚本。
htmlTemplates声明原始 HTML 模板,让自定义标签保留可读结构。
renderTags把自定义标签渲染成最终 DOM,适合 Element 风格封装。
renderBlock处理编辑器中的插件内容块。
i18n插件自己的中英文运行时文本。

私有插件

开源仓库只提交官方插件和项目自带插件。私有、不准备开源的插件放在 PrivatePlugins/,本地可同步使用,但默认不进入 git。

Plugins/         official plugins committed with the project
PrivatePlugins/  local/private plugins ignored by git

这样可以保持公开仓库干净,同时保留本地商业插件或实验插件的开发空间。

部署与环境变量

部署前先同步 secrets,再迁移远端 D1,最后部署 Worker。

npm run secrets:push
npm run db:migrate:remote
npm run deploy

.dev.vars、.env、.env.local、.wrangler/ 和 PrivatePlugins/ 默认不上传 git。

npm run db:init
npm run dev
npm run typecheck

本地开发先初始化 D1,再启动 dev server。初始化会执行迁移、同步官方插件,并把项目内置媒体写入媒体系统。提交前至少运行类型检查,涉及数据库结构时同步新增 migrations 文件。

内置媒体与图标

DocForge 的项目图标和内置图片不会只放在 public/ 里。部署流程会把它们同步到 R2,并在 D1 media 表建立索引,这样媒体页、图标选择器和 data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22960%22%20height%3D%22540%22%20viewBox%3D%220%200%20960%20540%22%3E%3Crect%20width%3D%22960%22%20height%3D%22540%22%20fill%3D%22%230d1117%22%2F%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22880%22%20height%3D%22460%22%20rx%3D%2218%22%20fill%3D%22none%22%20stroke%3D%22%2330363d%22%20stroke-width%3D%223%22%20stroke-dasharray%3D%2216%2012%22%2F%3E%3Ctext%20x%3D%22480%22%20y%3D%22252%22%20dominant-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22%238b949e%22%20font-family%3D%22Arial%2C%20sans-serif%22%20font-size%3D%2234%22%3EImage%20missing%3C%2Ftext%3E%3Ctext%20x%3D%22480%22%20y%3D%22306%22%20dominant-baseline%3D%22middle%22%20text-anchor%3D%22middle%22%20fill%3D%22%2358a6ff%22%20font-family%3D%22Consolas%2C%20monospace%22%20font-size%3D%2222%22%3E%7B%7Bimg%3Akey%7D%7D%3C%2Ftext%3E%3C%2Fsvg%3E 都能使用同一套资源。

npm run media:sync
npm run media:sync:remote

默认同步 DocForge favicon 的 PNG、SVG 和 ICO 版本,远程部署时该步骤已经包含在 npm run db:migrate:remote 中。

源文件媒体 Key
public/favicon.png写入 /media/docforge/favicon.png,占位符 key 为 docforge-favicon。
public/favicon.svg写入 /media/docforge/favicon.svg,占位符 key 为 docforge-favicon-svg。
public/favicon.ico写入 /media/docforge/favicon.ico,占位符 key 为 docforge-favicon-ico。

部署实例

实际部署实例可以使用单独目录维护,例如 DocForge-deploy-clean。这个目录只拉取公开仓库更新并部署,保留自己的 .dev.vars、wrangler.toml 绑定、R2/D1 数据和私有内容,不把本地实例改动提交回开源仓库。

git pull
npm run deploy:local

开源仓库负责产品代码和官方插件;部署实例负责自己的数据迁移、媒体、账号和站点配置。

文档可见性

文档有两个独立开关:启用访问控制 /slug 是否可打开;首页展示控制是否进入根路径文档列表。

状态可直接访问首页列表
禁用
启用,不进首页
启用,首页展示
这样可以让文档可直接访问,但不出现在 http://127.0.0.1:8787/ 首页列表。