Handsontable 文档指南页编写规范:Frontmatter、框架示例嵌入与 Sidebar 注册全解析
【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look & Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址: https://gitcode.com/gh_mirrors/ha/handsontable
本文基于 Handsontable 官方文档仓库中的.claude/skills/writing-docs-pages/SKILL.md技能说明,结合docs/目录下的真实页面(如 installation.md)、README-EDITING.md 编辑指南、AGENTS.md 文档标准,以及src/plugins/下的预处理插件源码,系统讲解如何为 Handsontable 文档站点编写、编辑和注册指南页面。读完本文,你将掌握 YAML frontmatter 的完整字段语义、四类 Diátaxis 页面结构、::: only-for框架条件内容、::: example可运行示例容器的全部选项、写作风格红线、sidebar 注册流程,以及 TypeScript 示例到 JavaScript 的自动化生成命令。
Handsontable 文档站点构建在 Astro Starlight 之上,同时保留了大量 VuePress 风格的 Markdown 语法(::: only-for、::: example、[[toc]]等),这些语法由自定义插件在构建期转换。因此,理解"写什么"与"底层如何解析"同等重要——前者保证页面符合规范,后者帮助你排查"为什么我的页面没按预期渲染"。
1. Frontmatter:每个.md文件的强制起点
按照 SKILL.md 的约定,docs/content/guides/下每个指南页面的.md文件都必须以 YAML frontmatter 开头:
--- title: Feature Name metaTitle: Feature Name - JavaScript Data Grid | Handsontable description: Short SEO description under 160 characters. permalink: /feature-name canonicalUrl: /feature-name tags: - keyword1 - keyword2 react: metaTitle: Feature Name - React Data Grid | Handsontable searchCategory: Guides category: Cell features # Must match a sidebar category exactly menuTag: new | updated # Optional; sidebar badge ---其中menuTag: new用于新建页面,menuTag: updated用于对已有页面做实质性内容修改;纯小修(错别字、代码片段/链接修正)以及 changelog、迁移指南页面则省略该字段,且不要动已存在的标签。
1.1 字段语义与默认值
README-EDITING.md 给出了每个字段的完整语义:
| 标签 | 含义 | 默认值 |
|---|---|---|
title | 页面标题(渲染为 H1) | 未设置时由父级页面标题生成 |
permalink | 页面的唯一URL | 未设置时由 Markdown 文件名生成 |
canonicalUrl | 页面最新版的 canonical URL | 无(非必需) |
metaTitle | 页面的 SEO meta 标题 | 无(非必需) |
description | 页面的 SEO meta 描述 | 无(非必需) |
tags | 文档搜索引擎使用的搜索标签 | 无(非必需) |
react/angular | 仅作用于对应框架版本的替代 frontmatter 集合 | 无(非必需) |
searchCategory | 搜索结果的分类 | 默认归入 "Guides" 分类 |
menuTag | 侧边栏菜单中页面标题旁的徽标 | 无(非必需) |
category | 页面所属内容分类(用于组织页面) | 无(非必需) |
1.2 按框架差异化 frontmatter
同一页面在不同框架版本下可以有不同的 meta 信息。例如 installation.md 的真实 frontmatter:
--- type: how-to title: Installation metaTitle: Installation - JavaScript Data Grid | Handsontable description: Install Handsontable through your preferred package manager, or import Handsontable's assets directly from a CDN. permalink: /installation canonicalUrl: /installation tags: - quick start react: metaTitle: Installation - React Data Grid | Handsontable angular: metaTitle: Installation - Angular Data Grid | Handsontable vue: metaTitle: Installation - Vue Data Grid | Handsontable searchCategory: Guides category: Getting started ---可用的框架键为react和angular(SKILL.md 所列),不过实际页面中vue键也被使用。框架键下不仅可以覆盖metaTitle、description,还能定义自定义值,这些值可在模板中消费,且仅对对应框架生效。
1.3 必须声明的type字段
AGENTS.md 要求每个页面必须在 frontmatter 中声明 Diátaxis 内容类型:
type: tutorial | how-to | reference | explanation四种类型对应读者不同的诉求:Tutorial(教学)、How-to guide(任务达成)、Reference(信息查阅)、Explanation(原理理解)。如果一页内容横跨两种类型,应拆分为独立页面。目录结构本身也隐含了类型预期:guides/getting-started/为 How-to,api/为 Reference,recipes/为 Tutorial。
2. 页面结构:无 H1、Overview、TOC 与渐进式小节
SKILL.md 明确了指南页的固定结构顺序:
- 正文中不写 H1——Starlight 会用 frontmatter 的
title字段渲染页面标题。如果在 frontmatter 之后再写# Title(或其他 H1),页面上会出现重复标题。 - Overview 概述——
---之后的第一段内容,用 1-2 句话说明该功能是什么、为什么重要。 [[toc]]——自动根据各级标题生成目录。这一宏由vuepress-preprocessor.mjs在构建期移除(Starlight 本身会自动渲染目录),见 vuepress-preprocessor.mjs:// 2. Remove [[toc]] (Starlight renders a ToC automatically) result = result.replace(/^\s*\[\[\s*toc\s*\]\]\s*$/gm, '');- 渐进式小节——只使用
##及以下层级,按"启用功能 → 基本用法 → 配置选项 → 高级用法 → 键盘快捷键 → 已知限制 → API 参考链接"的顺序组织。
2.1 分类型模板
AGENTS.md 为四种 Diátaxis 类型分别提供了模板。以 How-to 为例,其骨架为:Prerequisites(前置条件)→ Steps(有序步骤列表)→ Result → Related。## Steps下的有序列表会自动被渲染为 Starlight 步骤列表(rehype-migration-steps.mjs插件为紧随该标题的<ol>添加class="sl-steps" role="list"),因此直接写普通 Markdown 有序列表即可,无需手工添加任何标记。
3. 框架特定内容:::: only-for条件块
指南页需要同时服务 JavaScript、React、Angular、Vue 四种框架。用::: only-for容器包裹只适用于某个框架的内容:
::: only-for javascript JavaScript-only content here. ::: ::: only-for react React-only content here. :::关键约定::::标记必须独占一行,且内容块前后都要有空白行。
3.1 底层实现
该语法由 vuepress-preprocessor.mjs 中的filterOnlyForBlocks()实现,且必须最先执行。它维护一个栈结构,逐行扫描:遇到::: only-for <frameworks>开启标记时,判断当前框架是否在列表中;遇到内部嵌套的其他:::容器(如::: example、::: tip)时递增innerDepth;遇到裸:::闭合标记时递减。只有"所有外层 only-for 帧都命中当前框架"的内容行才会被保留输出,其他框架的内容被整体移除。
构建期框架解析的另一层证据在 framework-loader.mjs:自定义 Astro 内容加载器会为每个content/下的.md文件生成 4 个条目(JavaScript/React/Angular/Vue 各一),并附带框架前缀,例如react-data-grid/guides/getting-started/introduction。因此同一个源文件最终会渲染出四个框架版本。
4. 示例嵌入:::: example容器与@[code]指令
指南页最重要的能力是嵌入可运行的代码示例(带实时预览)。SKILL.md 给出的标准模式如下。
JavaScript / TypeScript 示例(--js 1 --ts 2设置标签页顺序):
::: only-for javascript ::: example #example1 --js 1 --ts 2 @[code](https://link.gitcode.com/i/f8cd9ce504e4cd3aaef8b07f47db7ae3) @[code](https://link.gitcode.com/i/3dced1c300e75843bada41ef967e7d76) ::: ::: ::: only-for react ::: example #example1 :react --tsx 1 --jsx 2 @[code](https://link.gitcode.com/i/c32da7355ef2f182f8e8adb5ccf7153e) @[code](https://link.gitcode.com/i/790e1b1f34dbc15ed836ef294f40cf32) ::: ::: ::: only-for vue ::: example #example1 :vue3 @[code](https://link.gitcode.com/i/b586f7b92de6d1a60456b06fdd588212) ::: :::规则要点:
- Vue 3:嵌入单个 TypeScript SFC(
vue/example1.vue,使用<script setup lang="ts">),使用:vue3预设(功能需要额外依赖时可用:vue3-languages、:vue3-vuex)。不要为新 Vue 示例使用--html/--js标签页。 - Angular:使用
:angular预设,配合--ts 1 --html 2。
4.1 容器选项完整参考
README-EDITING.md 给出了example容器的完整选项表:
| 选项 | 必需 | 示例 | 可选值 | 用途 |
|---|---|---|---|---|
#exampleId | 否 | #example1 | 字符串 | 容器唯一 ID |
.class | 否 | .new-class | 字符串 | 容器自定义 CSS 类 |
:preset | 否 | :hot | :hot|:hot-lang|:hot-numbro|:react|:react-languages|:react-numbro|:react-redux|:react-advanced|:angular|:angular-languages|:angular-numbro|:vue3|:vue3-numbro|:vue3-languages|:vue3-vuex | 设定代码依赖 |
--js <pos> | 否 | --js 1 | 正整数(默认1) | 设置 JS 代码片段在容器中的位置 |
--html <pos> | 否 | --html 2 | 正整数(默认0) | 设置 HTML 代码片段位置;0禁用 HTML 标签页 |
--css <pos> | 否 | --css 2 | 正整数(默认0) | 设置 CSS 代码片段位置;0禁用 CSS 标签页 |
--no-edit | 否 | --no-edit | --no-edit | 移除Edit按钮 |
--tab <tab> | 否 | --tab preview | code|html|css|preview | 设置默认打开的标签页 |
4.2 真实页面中的用法
以 installation.md 为例,JavaScript 部分嵌入示例:
::: example #example1 --js 1 --ts 2 @[code](https://link.gitcode.com/i/f8cd9ce504e4cd3aaef8b07f47db7ae3) @[code](https://link.gitcode.com/i/3dced1c300e75843bada41ef967e7d76) :::对应的示例源文件为 example1.ts 与 example1.js——注意它们都包含了licenseKey: 'non-commercial-and-evaluation'(非商业用途许可),这是文档代码示例的强制要求。
4.3 底层渲染原理
framework-loader.mjs 中的processExampleBlocks()在only-for过滤之后处理这些容器:解析#exampleId、CSS 类、--code-only标志,收集块内的@code引用,然后调用buildExampleHtml()生成最终输出。buildExampleHtml()(framework-loader.mjs)会:
- 依据目录路径(
/angular/、/react/、/vue/)而非扩展名判断框架,避免 JS 示例携带的.ts变体被误判为 Angular; - 为可执行示例生成带 loading 骨架屏的实时预览区、Source code切换按钮、Edit in sandbox与See on GitHub链接;
- 将 JS+TS(或 JSX+TSX)脚本归入同一个 "JavaScript" 标签页,支持语言下拉切换;HTML、CSS 作为独立标签页;
- 对无运行入口的服务端代码(PHP、Python、Ruby 等)退化为纯代码围栏展示。
5. 写作风格:Voice 与 Style 红线
写作风格细则完整收录于 AGENTS.md(文档站点专用,覆盖了 monorepo 级规范.ai/DOC-STANDARDS.md中与之冲突的部分)。SKILL.md 提炼的关键点:
- 主动语态、美式英语、短句。
- 以 "you" 称呼读者,绝不使用 "we";三个及以上并列项使用 Oxford comma(牛津逗号)。
- 禁用评价性形容词("easy"、"simple"、"obvious")。
- 用连字符(
-)或双连字符(--)分隔从句,不用 en dash——这是文档站点约定(与 JSDoc/changelog 使用 en dash 不同)。 - UI 元素加粗(如Add comment),API 名称用行内代码(如
comments)。 - 内部链接使用
text语法。 - 每个句子(包括列表项)以句号结尾。
AGENTS.md 补充的禁用词表:simply、just、easy、straightforward、note that、please、allows you to(改用 "lets you" 或主动改写)、in order to(改用 "to")、utilize(改用 "use")。标题与 frontmattertitle一律使用句首大写(sentence case),只大写首词、专有名词、产品名、API 标识符与缩略词,例如Use a cell renderer而非Use a Cell Renderer。只使用直引号("和'),禁用弯引号。
6. 商标规则
凡页面提到 "Excel",必须在页面底部包含 Microsoft/Excel 商标免责声明;同时提到 "Google Sheets" 的页面,使用同时覆盖两个商标的扩展版免责声明。免责声明以 callout 或脚注形式放在页面底部(详见 AGENTS.md)。
7. 内部链接与模板变量
7.1@/链接语法
README-EDITING.md 规定内部链接禁止使用绝对链接或相对 URL,统一采用@/前缀:
text规则细节:
@后跟目标文件相对当前版本根目录的路径,如[Clipboard](https://link.gitcode.com/i/982e12cdaa72855756623caf50420dc2);- 目标文件名必须带
.md扩展名,如Autofill; - 需要定位小节时使用锚点,如
Core; - 跨框架链接在
@后加框架名:[React methods](https://link.gitcode.com/i/db6b3d7e432276592f8d23137f2ea49e); - 目标文件必须定义了
permalinkfrontmatter;若生成 URL 失败,输出为相对链接兜底; - 未指定框架时,链接指向当前浏览的框架版本。
链接中的@/前缀由预处理插件统一转换为绝对路径(见 vuepress-preprocessor.mjs)。
7.2 模板变量
AGENTS.md 规定了五个构建期解析的模板变量,用于避免在文档中硬编码 GitHub 分支名(所有变量在 template-variables.mjs 中声明与替换):
| 变量 | 生产构建 | 其他构建 | 用途 |
|---|---|---|---|
{{$examplesBranch}} | prod-examples/<major> | master | handsontable/examples启动模板源码 |
{{$currentMinorVersion}} | prod-docs/<major>.<minor> | develop | handsontable/handsontable源码链接 |
{{$currentVersion}} | package.json 版本 | 0.0.0-next-<sha>-<date> | 版本字符串、runner 链接 |
{{$latestChangelogVersion}} | 最新changelog-N主版本 | 相同 | 最新 changelog 页链接 |
{{$basePath}} | '' | '' | 根相对资源路径 |
硬编码tree/master链接会让旧版本文档的读者跳转到与版本不匹配的模板(AGENTS.md 中的 DEV-2214),因此必须使用模板变量。唯一例外是server-side-*recipes 保留tree/master/server-examples/...。
8. Sidebar 注册:让新页面出现在导航中
创建新页面后,必须将其加入 sidebar.js。在正确的分类数组中插入条目:
{ path: 'guides/category/feature-name/feature-name' }若页面仅面向特定框架,使用onlyFor:
{ path: 'guides/getting-started/react-methods/react-methods', onlyFor: ['react'] }, { path: 'guides/getting-started/angular-hot-instance/angular-hot-instance', onlyFor: ['angular'] }, { path: 'guides/getting-started/vue3-hot-reference/vue3-hot-reference', onlyFor: ['vue'] },未在 sidebar.js 中注册的页面不会出现在导航中(AGENTS.md)。注意页面的categoryfrontmatter 必须与 sidebar 的分类标题精确匹配。侧边栏的New / Updated徽标由menuTag字段驱动,与 sidebar.js 无关。
9. 代码示例生成与质量校验
9.1 TypeScript 优先,JavaScript 自动生成
SKILL.md 规定:JavaScript 和 React 示例先编辑 TypeScript 源文件(.ts或.tsx),再从docs/目录生成 JavaScript 变体:
cd docs && npm run docs:code-examples:generate-js -- <path-to-ts-file>路径相对于docs/,例如content/recipes/foo/javascript/example1.ts。该命令对应 package.json 中的docs:code-examples:generate-js,实际由 transpile-doc-example.mjs 执行。Vue 示例则直接在.vue文件中编写 TypeScript(<script setup lang="ts">),没有单独的 JS 文件需要生成。
9.2 示例质量规则
AGENTS.md 对示例代码提出了硬性要求:
- 所有代码块必须带语言标签(
javascript、typescript、html、css、shell、json、```yaml),禁止无标签代码块; - 使用
const和let,禁用var; new Handsontable(...)调用必须包含licenseKey: 'non-commercial-and-evaluation';- 发布示例中禁止行内
// TODO或// ...注释; - 示例控制在 25-60 行之间,超出则改为链接到在线沙箱;
- 禁止占位数据(
foo、bar、A1、Column1、test等),必须使用领域真实数据(财务、HR、库存、分析、项目管理、科学等领域),且至少 5 行数据以便功能可见; - Angular 示例必须使用
standalone: true模式:CSS 走--css槽位(JIT 无法在运行时解析styleUrls)、模板内联、构造函数禁止注入服务(改用inject())、Hooks 放进gridSettings而非模板事件绑定、使用@for/@if/@switch内置控制流。
9.3 相关校验命令
| 命令 | 用途 |
|---|---|
npm run docs:code-examples:generate-js -- <path> | 由 TS 生成 JS 示例 |
npm run docs:test:plugins | 运行预处理插件单元测试 |
npm run docs:lint | ESLint 检查src与content |
npm run docs:validate-changelog-links | 校验 changelog 中的@/api/链接 |
npm run build | 依次执行docs:api、docs:validate-highlights、astro build与层序校验 |
npm run dev | 本地开发服务器(.md与示例源文件支持热重载) |
10. 提交前的自查清单
AGENTS.md 提供了文档 PR 的标准检查清单,关键条目包括:
- frontmatter 已添加
type:字段(tutorial | how-to | reference | explanation),且使用了对应类型的 Diátaxis 模板; - 标题符合类型命名约定(How-to 以 "How to ..." 开头,Explanation 以 "Understanding ..." 开头);
- 无禁用占位数据、所有示例数据领域真实且前后一致;
- 所有代码块带语言标签、无
var、示例含licenseKey; - 标题层级无跳级(如 H2 → H4)、标题与
title:使用句首大写; - 全文主动语态 + 第二人称,无禁用词;
- Tutorial / How-to 含 Prerequisites,Tutorial 含 "What you learned" 与 "Next steps",How-to 含 "Result";
- 新页面已注册到 sidebar.js,新页面设
menuTag: new、实质性修改设menuTag: updated; - 提及 "Excel" 时包含 Microsoft 商标免责声明;
- TypeScript 示例已存在,JS 通过
npm run docs:code-examples:generate-js生成。
另外需要注意:docs/content/**下存在由生成器维护的内容块(以<!-- option-levels:start -->/<!-- option-levels:end -->标记包裹),编辑任何指南页面前应先搜索:start -->标记,避免在生成块内手改导致下次生成时被覆盖(详见 AGENTS.md)。
深入阅读
- 技能原文:.claude/skills/writing-docs-pages/SKILL.md
- 完整编辑规则:docs/README-EDITING.md
- 文档标准与风格指南:docs/AGENTS.md
- 真实指南页范例:docs/content/guides/getting-started/installation/installation.md
- Sidebar 注册:docs/content/guides/sidebar.js
- 语法预处理实现:docs/src/plugins/vuepress-preprocessor.mjs
- 内容加载与示例渲染实现:docs/src/plugins/framework-loader.mjs
- 示例生成脚本:docs/scripts/transpile-doc-example.mjs
- 脚本入口:docs/package.json
【免费下载链接】handsontableJavaScript Data Grid / Data Table with a Spreadsheet Look & Feel. Works with React, Angular, and Vue. Supported by the Handsontable team ⚡项目地址: https://gitcode.com/gh_mirrors/ha/handsontable
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考