☰
Hexo文章创建与发布全流程:草稿、页面、模板与命名规范
2026/10/13 14:14:52 网站建设 项目流程

这个系列写到第四篇,我已经默认你有了一套能正常访问的 GitHub Pages 站点。最近在交流里看到挺多朋友卡在“写文章”这一步:命令敲了、本地也预览了,线上就是看不到新内容,翻来覆去怀疑自己部署步骤错了。

其实绝大多数情况都不是部署的问题,而是把文章和草稿的用途搞混了,或者创建完文章之后少了某些关键步骤。作为一个把 Hexo 从零摸到熟的人,这篇就把创建新文章、草稿的完整生命周期、页面体系搭建、模板定制、文件命名这些操作一次性讲透,全是实际能用上的细节。

1. 创建一篇文章的完整动作:命令、文件、布局三者关系

1.1 hexo new 到底做了哪几件事

新建文章最标准的命令是:

hexo new post "文章标题"

因为站点配置里的default_layout默认就是post,所以直接写hexo new "文章标题"也一样。

但很多人只记住了命令,没想过它背后做了什么。简单拆解一下,hexo new实际上完成了三件事:

  • 读取scaffolds/目录下对应的模板文件,本文这里就是post.md;
  • 在source/_posts/目录里新建一个 Markdown 文件;
  • 把命令行传入的标题和时间写入文件的 Front-matter 字段。

执行命令后,终端会返回类似这样的提示:

INFO Created: ~/blog/source/_posts/2024-06-01-my-first-post.md

注意文件名里带上了日期前缀,这是_config.yml中new_post_name配置决定的。后面第五节会专门讲要不要保留日期前缀这件事。

1.2 Front-matter 里那些字段到底怎么用

每个由 Hexo 创建的文章文件顶部,都会有一段用---包裹的区域,这就是 Front-matter。它本质上是文章的元数据,决定了文章在页面里显示什么、怎么归类、开不开评论等。

几个关键字段:

  • title:页面上显示的文章大标题,跟文件名是否一致完全无所谓;
  • date:发布时间,文章排序时会读它;
  • updated:更新时间,建议手动维护;
  • tags:标签,可以写多行,也支持层级;
  • categories:分类,注意分类是有父子层级概念的;
  • comments:是否开启评论;
  • cover:封面图路径,很多主题默认会读取;
  • description:描述信息,主题通常用在首页摘要或 SEO 描述里。

举个例子,我常用的文章头长这样:

--- title: 利用 Hexo 搭建个人博客的第四天 date: 2024-06-01 14:30:00 tags: - Hexo - GitHub Pages categories: - 博客搭建 cover: /images/hexo-cover.png ---

这里有个最容易踩的坑:title才是真正显示在页面上的标题。有些朋友发现新建文章后首页标题还是英文的,就是因为命令行参数写的是英文,而 Front-matter 里的title没有改成中文。

1.3 layout 字段:决定文章还是页面还是草稿

hexo new后面带的第一个参数叫布局(layout),它直接对应scaffolds/目录下的模板文件。

  • hexo new post "标题":用post.md模板,生成到_posts,是正式文章;
  • hexo new page "标题":用page.md模板,生成到独立目录,用于页面;
  • hexo new draft "标题":用draft.md模板,生成到_drafts,是草稿;
  • hexo new 自定义布局 "标题":只要scaffolds/下存在对应名字的模板文件,就会用那个模板。

文件放在哪个目录,比 Front-matter 里的字段更能决定它在整个渲染流程里的位置。_posts下的文章默认会被当作正式内容输出,_drafts下的草稿默认被忽略。这就是为什么有人新建了“文章”却始终看不到——他把文件创建到了草稿目录,发布流程自然不会处理它。

2. 草稿的生命周期:创建、预览、发布三步走

2.1 两种创建草稿的路径

如果你有一篇没写完的文章,最稳妥的做法不是放在_posts里硬憋,而是进入草稿机制。

命令创建草稿:

hexo new draft "一篇还没写完的文章"

命令执行后,文件会出现在source/_drafts/目录下。

如果你懒,也可以直接在_drafts目录手动新建一个 .md 文件,只要 Front-matter 头部信息写清楚,Hexo 同样会把它当成草稿。不过我还是建议用命令,因为模板会自动带上title、date,手写文件很容易漏字段或者把 YAML 格式写错。

草稿最有价值的地方,是它和线上内容天然隔离。你随时可以在本地写一半扔着,第二天接着写,线上访问者完全不会看到半成品。

2.2 本地预览草稿:hexo server 的隐藏参数

很多人创建草稿后,第一反应是执行hexo server启动本地预览,结果浏览器里压根看不到这篇文章。这不是 Hexo 出 bug 了,而是常规模式下它故意不去渲染草稿。

想让草稿也能在本地预览,启动服务时要加一个参数:

hexo server --draft

加上--draft之后,本地站点才会把source/_drafts下的内容渲染出来。这时候草稿里的排版、图片、代码块效果就都能检查了。

还有一个不推荐的配置:在站点_config.yml里设置render_drafts: true。这个设置会让所有生成命令都包含草稿,在非本地环境下运行hexo generate时,很容易把写了一半的内容意外发到线上。我一直不开这个开关,宁可启动服务时多敲几个字符。

2.3 草稿转正与正式发布:hexo publish 和部署

草稿打磨完,想把它变成正式文章,用 publish 命令:

hexo publish draft "一篇还没写完的文章"

这个命令的本质是把文章从source/_drafts/移动到source/_posts/,文件名和 Front-matter 内容基本不变。

转正之后,还需要走完整的发布流程:

hexo clean hexo generate hexo deploy

这里一定要养成先clean再重新生成的习惯。Hexo 有缓存机制,如果只是改了个文件名或调整了文章状态,不清缓存直接generate,非常容易出现线上还是旧页面的情况。

clean会清掉public目录,重新生成再部署,基本能消除绝大多数“改了没生效”的疑问。部署完也别立刻关电脑,花半分钟刷新一下线上地址,确认文章列表真的更新了,这个习惯能帮你省下不少排查时间。

3. 页面体系搭建:关于、标签、分类、归档从零配齐

3.1 页面和文章的本质区别

Hexo 里的“页面”和“文章”是两类东西。

文章会进入时间流,出现在首页列表、归档、标签和分类的聚合里;页面则更像一个“固定信息牌”,不属于时间流,适合放关于我、友情链接、项目展示这类长期不变的内容。

创建页面的标准命令:

hexo new page about

执行后生成source/about/index.md,Front-matter 类似:

--- title: about date: 2024-06-01 00:00:00 ---

注意这里的title只是页面标题的初始值,你可以直接改成:

--- title: 关于我 date: 2024-06-01 00:00:00 ---

页面访问路径依然是/about/,因为路径取决于目录名,跟title没关系。这个设计的好处是菜单地址可以保留英文短链接,页面显示标题却又可以是中文。

3.2 创建常见页面和调整菜单

一个完整的博客,通常需要四个基础页面:

hexo new page about hexo new page tags hexo new page categories hexo new page archives

执行完,source/下会多出四个目录。

但页面创建出来了,菜单可不会自动出现。菜单需要在主题配置文件里设置。多数主题用的键名是menu,配置大概是这种结构:

menu: 首页: / 归档: /archives/ 分类: /categories/ 标签: /tags/ 关于: /about/

注意不同主题对结尾斜杠的要求不一样,有的主题写成/about就行,有的必须/about/才会高亮当前菜单。最好先看一眼主题自带的示例配置,照抄它的格式最保险。

3.3 标签页、分类页、归档页的主题兼容性

只有页面文件还不够,标签页和分类页需要明确告知主题“这个页面是作为标签聚合页来渲染的”。常见写法是在 Front-matter 里加type字段:

--- title: 标签 date: 2024-06-01 00:00:00 type: tags ---
--- title: 分类 date: 2024-06-01 00:00:00 type: categories ---

但也有不少主题用layout: tags而不是type: tags。到底该用哪个,取决于主题内部模板的实现,没有统一答案。最靠谱的做法是翻主题自带的示例页面或者 README 文档,看它要求怎么填。

归档页稍微特殊一点,它通常不依赖某个独立页面,而是依靠主题对归档模板的实现。有的主题默认提供/archives/路由,有的则需要手动开启,还有些老主题根本不支持归档页。验证方法很简单:本地启动服务后直接访问/archives/,出现 404 就说明当前主题不支持或者需要额外配置。

如果是主题本身没有标签聚合模板,那创建了 tags 页面也可能打开后一片空白。这种情况对新手来说最好的解决方案是换主题,而不是自己补模板,除非你熟悉主题内部的模板语法。

3.4 自定义页面的几种玩法

除了常规四件套,自定义页面也很常用。比如友情链接页、项目展示页、相册页。

创建方式和普通页面一模一样:

hexo new page friend

生成source/friend/index.md后,直接在里面写 Markdown 内容就行。想让页面更好看,可以在主题里为它加一个独立布局模板,然后在页面头部声明layout: friend。

还有一个容易忽略的技巧:页面目录名支持子路径。比如:

hexo new page "photo/2024"

会生成source/photo/2024/index.md,访问路径就是/photo/2024/。做专题页面时很实用,但目录层级里尽量不要出现空格或特殊符号,否则 URL 编码问题会接踵而至。

4. 模板定制的逻辑:让新文章自动带上默认信息

4.1 默认模板文件的内容

scaffolds/目录是文章工厂的模具,默认包含post.md、page.md、draft.md三个文件。

默认的post.md通常长这样:

--- title: {{ title }} date: {{ date }} tags: ---

模板里用的是 Nunjucks 语法,{{ title }}和{{ date }}是 Hexo 在创建文件时注入的变量:前者来自命令行传入的标题,后者是当前时间。

有些朋友不理解模板里的tags:为什么没有值。这是 YAML 的写法,冒号后面留空,表示这个字段初始为空数组或者空值,等你写文章时再填。如果希望新文章自动带一个标签,可以写成tags: [默认标签]。

4.2 修改默认模板:给新文章加上分类和自定义字段

假设我写博客有个固定习惯:每篇文章默认分类为“博客搭建”,评论默认开启,再留一个自定义的subtitle字段。那我只要把scaffolds/post.md改成:

--- title: {{ title }} date: {{ date }} categories: - 博客搭建 tags: subtitle: comments: true ---

保存后,每次执行hexo new创建的新文章,都会自动带上这些默认字段。你只需要在写文章时补全subtitle和tags就行,不用每次从头敲。

如果想让某篇文章的时间不用当前时间,还可以用参数覆盖:

hexo new post "补交的一篇旧文" --date 2024-03-01 10:00:00

这个灵活度在补发早期文章时非常有用。

4.3 自定义模板:按文章类型生成不同骨架

默认三个模板之外,你可以根据自己的内容类型新增模板。比如我想要一个专门的“资源分享”模板,就在scaffolds/下新建share.md:

--- title: {{ title }} date: {{ date }} type: share tags: categories: link: password: ---

创建文章时指定布局:

hexo new share "一份值得收藏的资源清单"

这样生成的新文件会使用share.md作为模板,并且带有type: share字段。如果你的主题有对应的share布局,渲染时还会自动选用它。

这个思路可以扩展到读书笔记、周报、流水账等任何内容类型。掌握模板机制之后,写不同类别的文章会轻松很多,相当于把一个空文件包装成了带默认元数据的标准骨架。

5. 文件名与博客标题的规划:别让命名拖后腿

5.1 文件名、标题、URL 三者的关系

很多新人对这三者的关系理不清,我用最简单的话概括:

  • 文件名是磁盘上 .md 文件的名字,也是 URL 短链的主要来源;
  • 标题是 Front-matter 里的title,只决定页面显示什么字;
  • URL 由站点配置里的permalink规则生成,默认是“年/月/日/短标题”。

默认permalink配置是这样的:

permalink: :year/:month/:day/:title/

假设文件名是2024-06-01-my-post.md,最终 URL 就是:

/2024/06/01/my-post/

这里的:title是文章 slug,一般取文件名,但会自动剥离掉日期前缀这样的辅助部分。所以文件名本身要尽量可读、简短、语义明确。

如果你图省事用了中文文件名,比如我的文章.md,最终 URL 会变成:

/2024/06/01/%E6%88%91%E7%9A%84%E6%96%87%E7%AB%A0/

浏览器能访问,但链接又长又丑,分享给别人时一眼看不出内容。所以我的明确建议是:文件名永远使用英文字母、数字、连字符,不用中文、空格、下划线。

5.2 配置 new_post_name 和 permalink

控制新建文件名的配置是new_post_name,默认值:

new_post_name: :year-:month-:day-:title.md

这个配置会影响hexo new创建文件时的命名方式,但不会影响已存在的文件。

我的个人偏好是把文件名从“日期+标题”改成纯标题:

new_post_name: :title.md

为什么不做日期前缀?因为日期会写进文件名里,一旦某天你手动调整文章 Front-matter 里的date字段来改变发布时间排名,文件名和实际发布时间就对不上了,维护起来很别扭。不带日期,文件目录也更干净。

如果还是想让文件名包含日期,又嫌默认方式太长,可以考虑:

new_post_name: :year-:month-:title.md

去掉“日”这一层,视觉上的噪音会小不少。这是个取舍问题,看你更在意文件名体现时间,还是更在意文件名的清爽程度。

5.3 手动指定文件名和路径的技巧

hexo new支持一个--path参数,可以手动指定生成的文件名和路径。在下面三种场景特别有用:

  • 想要一个简短语义化的文件名,而不是标题去掉空格后的效果;
  • 想把某些文章按主题放进子目录;
  • 新建文章有固定编号,希望文件名以编号开头。

命令示例:

hexo new post "这篇文章我要用自定义文件名" --path custom-slug

生成后会得到source/_posts/custom-slug.md。路径里也可以包含子目录:

hexo new post "子目录文章" --path guides/custom-slug

生成后为source/_posts/guides/custom-slug.md,URL 会带上guides/。

用--path时有个小坑:如果路径或文件名包含空格,Hexo 不会自动做转换,最终会生成一个很怪的文件名。所以我只用连字符,不用空格或下划线。下划线虽然在 URL 里也可使用,但不少第三方服务和阅读器对下划线的处理方式不一致,连字符是最稳妥的。

我印象很深的一次是写某个技术复盘文章,文件名用了Hexo_部署问题记录.md这种风格,结果文章里的相对路径图片在个别浏览器里被转义错误,重新生成还是老样子。改成hexo-deploy-troubleshooting.md后,所有问题立刻消失了。命名这种事,当时觉得无所谓,后面会以意想不到的方式找回来。

最后一个实际经验:写正文时,不要把标题再写成一个 Markdown 的一级标题# 标题。很多主题渲染文章页时会把 Front-matter 里的title自动渲染成页面的 H1,正文里再写一个# 标题,页面上就会出现两个大号标题,非常难看。正文直接从小节开始写就行,一级标题的位置留给主题自动生成。

每次创建完文章,先打开文件扫一眼 Front-matter,确认模板字段、标题、分类、日期都没问题,再开始写正文。这个习惯看着很小,长期用下来能避免大量无意义的返工,写博客这件事也会顺很多。

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

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

立即咨询