内容仓库结构与写作约定

这个仓库里只装文章本身:正文、frontmatter、每篇自己的图片。它不装代码、不装构建产物,也不依赖任何数据库。这篇说明目录该怎么摆、frontmatter 每一项是什么意思、以及图片为什么必须用相对路径。

这是一篇示例文章,用来演示这个内容仓库的完整结构。你可以把它删掉,但建议先照着它抄一份骨架。

#一篇一目录

每篇文章是 posts/ 下的一个目录。目录名就是这篇文章的 slug,也就是它在网址里的那一段:

posts/content-repo-conventions/     ← 目录名 = slug = /posts/content-repo-conventions
├── index.md                        ← 必需,正文与 frontmatter 都在这
└── assets/                         ← 本篇专属图片
    ├── cover-16x9.webp
    └── structure-diagram.webp

两个容易踩的点:

  1. 目录里必须有 index.md。少了它,这篇文章会被静默跳过——不报错,URL 直接 404。这是整个结构里最难排查的一处。
  2. 不支持按年份分层。posts/2026/xxx/index.md 是不会被识别成文章的。想按时间组织,靠 date 字段,不靠目录。

#图片为什么必须用相对路径

正文里引用自己的图,只写 ./assets/...:

内容仓库的结构示意

不写 https://...,也不写 /img/...。原因不是洁癖:

写法问题
https://cdn.example.com/a.png把真相源绑死在某个 host 上。换个图床、换个域名,链接就断
/img/a.png指向站点根目录,等于假设「所有图片都堆在同一处」。文章一多就管不住
./assets/a.png跟着文章目录走。把整个目录搬到哪都还是对的

构建时会把 ./assets/a.png 解析成本文目录下的真实文件,读出宽高,然后把 width/height 写进渲染结果。读不出宽高就会构建失败——没有尺寸的图会造成布局跳动,这是硬拦,不是警告。

#frontmatter 字段

index.md 顶部那段 --- 之间的内容。除了 updated、cover、series 这几个可选项,其余都是必填:

字段约束
title不超过 40 字
slug小写字母、数字、连字符,且必须等于目录名
dateYYYY-MM-DD,必须是真实存在的日期
category四选一,不能自创
tags1–4 个
summary60–120 字。列表页和搜索结果里显示的就是它
drafttrue 不进构建。没有默认值,必须显式写

category 目前只有四个值:

  • 工程实践
  • 阅读笔记
  • 生活随笔
  • 工具箱

自创第五个值会让构建直接失败。要加分类,得先改校验规则,不是改文章。

#静态页与数据文件

除了文章,仓库里还有两类东西:

pages/          扁平 .md 文件,一个文件一个页面
  about.md      →  网址 /about

data/           给首页用的结构化数据
  links.yaml    →  友链列表
  now.yaml      →  首页「近况条」

pages/ 和 posts/ 的区别很重要:pages/ 是扁平文件,posts/ 是一个个目录。 把 pages/about.md 写成 pages/about/index.md,这个页面就不存在了。

#写完之后

这个仓库只负责存内容。渲染、图片处理、搜索索引都在另一个仓库里做。所以这里的检查只有一条:能不通过校验。

校验过不去,构建会当场停下,报错信息会指出是哪个文件、哪个字段、期望什么值。与其等构建报错,不如写完在本地先跑一遍校验再提交。

一句话总结:文章的目录名就是它的网址,图片跟着目录走,frontmatter 写错就构建失败。 记住这三条,这个结构就不会用错。