☰
30 seconds of code 文章编写规范:读懂 snippet-template 内容模板与 Frontmatter
2026/10/1 8:47:52 网站建设 项目流程
  • 教程
  • 文档

【免费下载链接】30-seconds-of-code

Coding articles to level up your development skills

项目地址:https://gitcode.com/gh_mirrors/30/30-seconds-of-code
点击查看免费下载

30 seconds of code 仓库中的所有文章(Article)都遵循统一的 Markdown 文件格式:文件顶部是 YAML Frontmatter,用于声明标题、语言、标签、封面等元数据;下方是正文。本文以仓库中的模板文件 content/snippets/articles/snippet-template.md 为骨架,结合 src/models/snippet.js、src/models/contentModel.js 等源码,逐字段解释模板的含义、取值规则与底层处理逻辑,帮助你写出能被站点正确收录、检索与发布的文章。

模板总览:一个文章文件由什么组成

在 30 seconds of code 中,一篇文章就是一个.md文件,存放在 content/snippets/articles 目录(正式文章位于其s/子目录中,例如 content/snippets/articles/s/markdown-cheatsheet.md)。模板文件全文如下:

--- title: My amazing story shortTitle: Amazing story language: javascript tags: [webdev] cover: image excerpt: A short summary of your story up to 140 characters long. listed: true dateModified: 2021-06-13 --- Write your story here.

文件结构可以拆成两部分:

  1. Frontmatter(元数据区):---包裹的 YAML 块,声明文章的标题、语言、标签等 8 个字段;
  2. 正文区:Frontmatter 之后的所有 Markdown 内容,即文章的实际正文。

从源码看,这两部分会被分别消费:src/lib/contentUtils下的解析工具负责把 Frontmatter 解析成结构化字段,而正文则被 src/models/snippet.js 中的this.content读取(见content字段赋值),再通过enrichedContent等 getter 做进一步处理。

Frontmatter 字段逐一拆解

title:文章标题

title: My amazing story

title是文章的完整标题。在 src/models/snippet.js 中,this.title = data.title直接对应此字段。它同时影响:

  • SEO 标题:seoTitlegetter 会在标题中拼接语言名。对于javascript语言的文章,若第一个标签是node,则使用格式化后的标签名,否则使用语言名JavaScript;只有当title已包含该语言名时才不重复拼接。
  • 面包屑与推荐:title是面包屑和推荐系统的显示文本来源之一。

注意:title与shortTitle不同,前者用于完整展示,后者用于卡片、内嵌预览等紧凑场景。

shortTitle:短标题

shortTitle: Amazing story

shortTitle是文章的简短标题,主要用于列表卡片、搜索自动补全和<article-embed>内嵌预览场景。在 src/models/contentModel.js 的previewTitlegetter 中可以看到:Snippet 类型取this.title,而 Collection 类型取this.shortTitle;在asEmbedding()生成的<h4>内嵌链接中,展示的也是shortTitle。

language:所属语言

language: javascript

language声明文章所属的编程语言或主题域,取值对应 content/languages 目录下的语言定义文件(如 content/languages/javascript.yaml、content/languages/python.yaml、content/languages/git.yaml 等)。文章(Article)一般以javascript或webdev相关语言标记。

该字段通过 src/models/language.js 的Language.find(this.languageId)解析为语言对象,并驱动seoTitle中的语言前缀拼接。若language指向一个未注册的语言,hasLanguage会返回false,此时 SEO 标题与预览标签会退回到文章标题或主标签。

tags:标签列表

tags: [webdev]

tags是 YAML 数组,声明文章所属的标签。在 src/models/snippet.js 中,它被data.tags.split(';')从字符串拆分为数组,第一个标签即primaryTag,用于 SEO 标题与预览标签的格式化(formatTag来自 src/lib/stringUtils.js)。

值得注意的实践:

  • 第一个标签是"主标签",会影响 SEO 标题的拼接方式;
  • 若包含站点配置中的更新日志标签(settings.collections.updateLogTag),该文章会被识别为更新日志条目(isUpdateLog),供updateLogs查询筛选;
  • 标签同时也是搜索与推荐系统的重要信号,src/lib/search 目录下的索引构建会消费标签信息。

cover:封面图

cover: image

cover指定文章的封面图名称(不含扩展名)。封面图文件位于 content/assets/cover 目录,例如laptop-view对应laptop-view.jpg。图片经构建流水线转换为 WebP 格式输出到 public/assets/cover。

封面图的 URL 生成逻辑集中在 src/presenters/coverPresenter.js,并通过 src/models/contentModel.js 的coverUrl、coverSrcset、coverFullUrl等 getter 暴露给模板使用。模板中的占位值image只是示意,实际编写时请填一个真实存在的封面图文件名。

excerpt:摘要

excerpt: A short summary of your story up to 140 characters long.

excerpt是文章的简短摘要,模板注释明确要求不超过 140 个字符。它最终会进入description字段,用于:

  • 站点的 SEO 描述(seoDescription,经StringUtils.stripHtml清理 HTML);
  • 卡片与内嵌预览中的摘要文本(formattedDescription);
  • 搜索索引中的文本信号。

listed:是否列出

listed: true

listed是布尔值,控制文章是否出现在站点列表中。其语义在 src/models/contentModel.js 的listed()/unlisted()查询,以及 src/models/snippet.js 的isListedgetter 中体现:

get isListed() { return this.listed && this.isPublished; }

即:文章只有在listed: true且已发布(isPublished)时才被列出。listed: false的文章不会出现在公开列表,但仍可被保留在仓库中。

dateModified:最后修改日期

dateModified: 2021-06-13

dateModified是文章的最后修改日期,格式为YYYY-MM-DD。它在 src/models/snippet.js 中被解析为Date对象(new Date(data.dateModified)),并驱动三套关键逻辑:

  • 排序:byNew()按dateModified降序排列,last30Days()筛选最近 30 天更新的内容;
  • 发布/排期:published()/scheduled()分别筛选dateModified早于/晚于当前时间的文章;isPublished/isScheduled也是基于此判断——这意味着把dateModified设为未来日期即可实现"排期发布";
  • 展示:dateFormatted、dateMachineFormatted、dateShortString分别提供长格式、ISO 格式与短格式的日期字符串。

正文区:Markdown 与特殊语法

Frontmatter 之后就是正文。正文支持标准 Markdown(参见 content/snippets/articles/s/markdown-cheatsheet.md 中的标题、段落、强调、列表、链接、图片、代码、引用、表格等基础语法),此外还支持仓库自定义的扩展语法:

<article-embed>内嵌引用:在正文中写入<article-embed ref="..." title="..."/>可以引用仓库内的其他内容条目。其处理逻辑见 src/models/snippet.js 的enrichedContentgetter:源码用正则匹配<article-embed ref="(?<ref>[^"#]+)(?<hash>#[^"]+)*" title="(?<title>[^"]+)"/>,随后通过ContentModel.searchContentModels(ref)查找被引用条目,若目标isEmbeddable则调用asEmbedding()生成带封面图、标题、描述的内嵌卡片 HTML;否则替换为空字符串。

从模板到集合:文章与 Collection 的关系

文章文件本身是 Snippet 模型,而 content/collections 目录下的 YAML 文件(如 content/collections/js/index.yaml)负责把多个文章/代码片段组织成集合。集合模板 content/collection-template.yaml 展示了其字段结构:

slug: my-collection title: My awesome collection shortTitle: My collection listed: true snippetIds: - js/s/array-initialization - js/s/initialize-array-with-values - js/s/initialize-array-with-range - js/s/initialize-2d-array splash: plant-screen description: >- Explain the collection's topic in a few sentences. shortDescription: >- A short description of your collection up to 140 characters long.

可以看到:

  • snippetIds是文章/代码片段的 ID 列表,定义集合的成员;
  • splash指定集合的封面图(对应 content/assets/splash 下的图片);
  • description/shortDescription提供集合的完整与简短描述。

文章与集合的关联关系由 src/models/collectionSnippet.js 维护,src/models/snippet.js 通过collectionSnippets和collectionsgetter 反查文章所属的集合;若文章设置了journeyId,还会参与系列文章(Journey)的上一篇/下一篇分页(previousJourneySnippet/nextJourneySnippet/journeyPagination)。

写作风格规范

除了模板字段,仓库的 CONTRIBUTING.md 还明确了内容写作的通用规范,主要包括:

  • 语言:使用受众能理解的语言,统一美式拼写,句子尽量不超过 20 个单词,每个句子只聚焦一个要点;
  • 语气:优先使用主动语态;文档代码片段使用祈使句(如 "use this method");
  • 阅读难度:目标为 10 年级(Grade 10)阅读水平或以下,避免行话和含混的习语;
  • 方向性语言:尽量用 "previous" / "following" 代替 "above" / "below" 来指代章节;
  • 修改范围:网站内容相关的改动只修改content/snippets或content/collections目录下的文件。

校验与发布链路

写完文章后,其可发布性由源码中的查询逻辑决定:

  • isPublished:dateModified不晚于当前时间(未来日期则处于"已排期"状态);
  • isListed:listed: true且已发布;
  • 搜索索引:docTokens、recTokens等字段会进入搜索与推荐系统(相关逻辑见 src/lib/search 与 src/models/snippet.js 的recommendedSnippets),确保文章可被检索与推荐。

简而言之,一篇合规的文章需要:真实存在的cover图片、不超过 140 字符的excerpt、正确的language/tags取值,以及符合格式的dateModified。对照 content/snippets/articles/snippet-template.md 模板逐项填写,再参考同目录下的 content/snippets/articles/s/markdown-cheatsheet.md 等真实文章,即可快速产出与站点体系兼容的内容。

  • 教程
  • 文档

【免费下载链接】30-seconds-of-code

Coding articles to level up your development skills

项目地址:https://gitcode.com/gh_mirrors/30/30-seconds-of-code
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询