- 教程
- 文档
【免费下载链接】30-seconds-of-code
Coding articles to level up your development skills
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.文件结构可以拆成两部分:
- Frontmatter(元数据区):
---包裹的 YAML 块,声明文章的标题、语言、标签等 8 个字段; - 正文区:Frontmatter 之后的所有 Markdown 内容,即文章的实际正文。
从源码看,这两部分会被分别消费:src/lib/contentUtils下的解析工具负责把 Frontmatter 解析成结构化字段,而正文则被 src/models/snippet.js 中的this.content读取(见content字段赋值),再通过enrichedContent等 getter 做进一步处理。
Frontmatter 字段逐一拆解
title:文章标题
title: My amazing storytitle是文章的完整标题。在 src/models/snippet.js 中,this.title = data.title直接对应此字段。它同时影响:
- SEO 标题:
seoTitlegetter 会在标题中拼接语言名。对于javascript语言的文章,若第一个标签是node,则使用格式化后的标签名,否则使用语言名JavaScript;只有当title已包含该语言名时才不重复拼接。 - 面包屑与推荐:
title是面包屑和推荐系统的显示文本来源之一。
注意:title与shortTitle不同,前者用于完整展示,后者用于卡片、内嵌预览等紧凑场景。
shortTitle:短标题
shortTitle: Amazing storyshortTitle是文章的简短标题,主要用于列表卡片、搜索自动补全和<article-embed>内嵌预览场景。在 src/models/contentModel.js 的previewTitlegetter 中可以看到:Snippet 类型取this.title,而 Collection 类型取this.shortTitle;在asEmbedding()生成的<h4>内嵌链接中,展示的也是shortTitle。
language:所属语言
language: javascriptlanguage声明文章所属的编程语言或主题域,取值对应 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: imagecover指定文章的封面图名称(不含扩展名)。封面图文件位于 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: truelisted是布尔值,控制文章是否出现在站点列表中。其语义在 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-13dateModified是文章的最后修改日期,格式为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
相关推荐
30-seconds-of-code 内容创作指南:HTML 文章片段模板与 frontmatter 字段深度解析
30 seconds of code 内容创作指南:HTML 文章片段模板与 frontmatter 字段深度解析 在 30 seconds of code 开
教程文档30 seconds of code 贡献写作规范:从风格指南到内容入库的实战手册
30 seconds of code 贡献写作规范:从风格指南到内容入库的实战手册 30 seconds of code 是一个由社区驱动的编程速查与文章项目,
教程文档30 seconds of code:用 Git 提交信息模板(commit.template)统一团队提交规范
30 seconds of code:用 Git 提交信息模板(commit.template)统一团队提交规范 导读 在团队协作中,提交信息(commit m
教程文档
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考