这篇文档的作用是当模板用:想写新文章时,复制这篇的结构改一改就行。

一篇文章长什么样

文件放在 content/posts/ 目录下,文件名建议用 日期-英文短名.md:

content/
├── about.md
└── posts/
    ├── 2026-09-20-hello-blog.md
    └── 2026-09-22-markdown-cheatsheet.md

文件开头是 front matter(两行 --- 夹起来的配置):

---
title: 文章标题
date: 2026-09-22
tags: [Markdown, 使用指南]
summary: 首页列表里显示的摘要,不写就自动截取正文。
draft: false
---

draft: true 的文章不会被构建出来,适合写一半先存着。

标题

# 到 ###### 分别是六级标题。文章里一般只用到 ## 和 ###,它们会自动进入右侧目录。

三级标题长这样

四级标题就很少用了

强调和链接

**粗体** → 粗体,*斜体* → 斜体,~~删除线~~ → 删除线,`行内代码` → 行内代码。

链接写法是 [文字](网址),比如 一个不存在的示例链接;裸网址也会自动识别:https://example.com

列表

无序列表用 -、* 或 +:

  • 第一项
  • 第二项
    • 缩进两格就是子项
    • 再来一个子项
  • 第三项

有序列表用数字加点:

  1. 打开终端
  2. 进入站点目录
  3. 运行构建命令
  4. 把 site/ 目录上传

待办清单用 - [ ] 和 - [x]:

  • 写完草稿
  • 配一张封面图
  • 发布前通读一遍

代码

行内代码用反引号,比如 python3 build.py --serve。整段代码用三个反引号包起来,并在开头写上语言名:

from pathlib import Path

def count_words(text: str) -> int:
    """统计中文字符 + 英文单词数量。"""
    return len([c for c in text if "\u4e00" <= c <= "\u9fff"])

if __name__ == "__main__":
    p = Path("content/posts")
    for f in sorted(p.glob("*.md")):
        print(f.name, count_words(f.read_text(encoding="utf-8")))
# 构建 + 本地预览
python3 build.py --serve
# 换个端口
python3 build.py --serve --port 9000

代码块右上角有「复制」按钮,语言名会自动显示在左上角。

表格

语法效果备注
**文本**粗体前后不加空格也认
*文本*斜体中文里要小心使用
`代码`代码短命令用这个
---分隔线单独一行才生效

引用和分隔线

引用用来放别人的话,或者放一句自己想说但不好意思当正文写的话。

引用里可以嵌套列表:

  • 像这样
  • 还有这样

三个减号 --- 单独一行就是分隔线:


图片

图片写法是 ![说明文字](图片地址),地址可以是相对路径,也可以是完整网址。把图片都放在 static/images/ 里,构建时会自动复制到 site/images/:

  • ![图](../images/封面.png) —— 相对路径,文章页在 site/posts/ 下,所以要用 ../;
  • ![图](/images/封面.png) —— 站内根路径,构建时自动改写成正确的相对路径,推荐用这种,复制到哪一层都不会断。

站内链接同理:写 [另一篇](/posts/hello-blog.html),无论在文章页还是关于页,生成出来的链接都会自动对。

写完检查这四件事

  1. front matter 里的 title 和 date 有没有写对;
  2. 摘要(summary)读起来是否像一句人话;
  3. 代码块里的命令自己跑一遍,别让读者踩坑;
  4. 有没有哪句话其实是在凑字数——删掉。