前言

hexo 一点问题(生成博文插入本地图片,修改文章路径)

这篇文章之前谈过一点。

说明

在各个静态博客网站生成工具之间迁移文章时,可能会遇到链接不一致的问题。

比如你在 jekyll 配置好了,文章链接是 https://hqweay.cn/2019/09/23/new-post 。迁移到 hexo ,文章链接又变成了 https://hqweay.cn/2019/09/23/2019-09-23-new-post

通常,为了 SEO、使用第三方评论、或其它原因,我们总希望博客迁移后,链接保持能不变。

这里讨论一下我使用 jekyllhexohugo 在迁移数据时关于链接问题的一些感想。


先给一下方案,我建议文章按照 year-month-day-title.md ,即 年-月-日-标题.md 的格式命名。比如 2019-09-22-new-post.md 。之所以建议这样命名,是因为 jekyll 要求文章的文件名必须遵循这种格式。而 hexohugo 则没有这样的要求,后两者默认 文件名 作为标题。

以这种方式命名,hexohugo 仍可以通过配置获取到真正的 title 。而若不这样这样命名,如果想使用 jekyll 还得修改文件名。

虽然我觉得接触过 hexo 和 hugo 的人恐怕不会想着回到 jekyll 了吧…

而且通过年、月、日、标题的命名,在文件夹排列看起来比较清爽,同时还可以避免文件名冲突。


而生成的链接,我建议使用 /year/month/day/title ,比如 https://hqweay.cn/2019/09/23/new-post

如果只用 title 作为链接,比如 https://hqweay.cn/new-post ,若两篇文章 title 一样的话,就 可能 会冲突。用年、月、日、标题确定唯一的文章,就很难冲突啦。

这点和上面文件夹命名同理。

其实只是为了不冲突,https://hqweay.cn/2019-09-23-new-post 这样的链接也行。不过把时间区分出来观感好点…


给出方式。

如何配置

jekyll

文件名 :year-month-day-title.md

配置文件 _config.yml 添加

permalink : /:year/:month/:title

hexo

文件名 :year-month-day-title.md

配置文件 config.yml 添加

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

hugo

文件名 :year-month-day-title.md

配置文件 config.toml

[frontmatter]
date  = [":filename", ":default"]

[permalinks]
post = "/:year/:month/:day/:slug/"

这里先提一下,post = "/:year/:month/:slug/" 这条配置规则指的是 hugocontent文件夹下的 post 文件夹下的文章都用这条规则来解析。

如果 content 文件夹下还有其它文件夹,则其它文件夹下的文章的链接解析不受此规则影响。

比如 content 下有 studylife 两个文件夹,则两者都需要配置上。

[frontmatter]
date  = [":filename", ":default"]

[permalinks]
study = "/:year/:month/:slug/"
life = "/:year/:month/:slug/"

为啥呢?

说明

先提一下,现在手上没有 jekyll 环境,也没看过源代码,以下都是我的猜测理解…

一般的静态网页生成工具都提供文件名与链接地址的映射。

比如文件名为 2019-09-23-new-post.md ,若生成静态页面且部署后,访问的链接可能是这样的。

https://hqweay.cn/2019-09-23-new-post

观察这个链接,会注意到文件名被直接解析为文章链接的后缀。


静态网页生成工具通常通过 permalink 这个属性来配置链接的生成规则。permalinkPermanent Link 的缩写,可译作 永久链接 ,简单来讲,也就是指一个 url 对应一篇文章。


jekyll 中,文章的命名格式是 2019-09-23-new-post.md ,即 year-month-day-title.md 。这种命名格式是 jekyll 的要求。


在默认情况下,若配置文件中不配置 permalink ,或者配置 permalink: date ,链接就被解析为 https://hqweay.cn/2019/09/23/new-post.html

——注意,上面这样配置,会跟上后缀 .html

若配置为 permalink : /:year/:month/:title ,链接则解析为 https://hqweay.cn/2019/09/23/new-post

没有 .html 后缀。

具体配置方式比较多,详见官方文档。

从 jekyll 迁移至 hexo

hexojekyll 的不同之处在于,hexo 可以取博文在 Front Matter 中定义的时间

写文章时常常有这样的内容。

---
layout: post
title: 快乐星猫
date: 2017-08-20
categories: life
toc: true
tags: [充数]
description:
---

我是一只猫,快乐的星猫~

--- 中间那一坨就是 Front Matter

jekyll 规定了文件名格式为 year-month-day-title.md ,就是为了从文件名取 date

hexo 默认文件名为 title ,它优先从 front matter 里取 date


hexo 的链接和配置文件中两条属性相关。

permalink: :year/:month/:day/:title/ 链接的格式

new_post_name: :title.md 解析标题方式

上面列出来的是默认配置。

在默认配置下,如果文件名为 2019-09-23-new-post.md ,解析出来的链接为 http://hqweay.cn/2019/09/23/2019-09-23-new-post/

不对劲吧。

这就是因为在 hexopermalink 里,默认的 :year:month 等使用的是 front matter 里的 date


我们分析下链接 http://hqweay.cn/2019/09/23/2019-09-23-new-post/

前面的 2019/09/23 对应的是 front matter 里的 date,后面的 2019-09-23-new-post 对应的则是文件名。


为啥?

上面提到了。jekyll 要求的文件名格式是 year-month-day-title.md ,就是为了把文件名中的 yearmonth 等取为 date 。但是 hexo 没这个要求,文件名格式就是 title.md 。即,默认文件名作为 title。然后,取 front matter 里的时间作为 date


那咋整呢?如果要把博文从 jekyll 迁移到 hexo ,这不是有冲突吗。

这就需要用到上面的第二条属性了。

new_post_name: :title.md 解析标题方式

new_post_name 可以配置解析文件名的方式。

默认 new_post_name: :title.md 就是把文件名作为 title。

修改为 new_post_name: :year-:month-:day-:title.md

这时候,hexo 就会把文件名中定义的时间当作 date 使用了。


回头看一下。文件名为 2019-09-23-new-post.md

配置

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

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

此时,链接就为 http://hqweay.cn/2019/09/23/new-post/ 了。

从 hexo 迁移至 hugo

hugohexo 类似,默认以文件名作为 title

即便我们没使用过 hugo ,也可以畅想一下,hugo 里有没有类似 hexo 这样的配置?

一:配置解析链接的规则。

二:从文件名提取真正的 title

带着疑问查看文档。

首先看到了 permalinks 的配置。

https://gohugo.io/content-management/urls/#permalinks

[permalinks]
posts = "/:year/:month/:title/"

Only the content under posts/ will have the new URL structure. For example, the file content/posts/sample-entry.md with date: 2017-02-27T19:20:00-05:00 in its front matter will render to public/2017/02/sample-entry/index.html at build time and therefore be reachable at https://example.com/2017/02/sample-entry/.

只有 /posts 文件夹下的文件才会匹配这条链接解析规则。如,文件 content/posts/sample-entry.md ,它在 front matter 里配置了 date: 2017-02-27T19:20:00-05:00 。这个文件在 build 时就会被渲染为网页,放至 public/2017/02/sample-entry/index.html ,通过链接 https://example.com/2017/02/sample-entry/ 访问。

这样可以配置解析链接的规则,但同时也如文档所说,此时使用的 datefront matter 里定义的,而且 title 是文件名

瞧瞧 hugo 文件的 front matter

瞧瞧 front matter

---
title: "快乐星猫"
date: 2019-09-23T23:00:01+08:00
draft: true
---

注意!默认生成的文章中, date 使用的时间格式是 YYYY-MM-DD HH:MM:SS +0800 。(格式不作说明了。)

没看文档,网上资料说时间格式必须这样。从 hexo 迁移到 hugo ,也需要注意这个,把时间修改一下。

但是我貌似没修改也渲染出来了…

不过我现在不打算折腾 hugo,这个疑问先留着吧…

不改也是可以的!!

frontmatter

那有没有解析文件名的配置呢?

这里~


https://gohugo.io/getting-started/configuration/

:filename

Fetches the date from the content file’s filename. For example, 2018-02-22-mypage.md will extract the date 2018-02-22. Also, if slug is not set, mypage will be used as the value for .Slug.

An example:

> [frontmatter]
> date  = [":filename", ":default"]
> ```
>
> The above will try first to extract the value for `.Date` from the filename, then it will look in front matter parameters `date`, `publishDate` and lastly `lastmod`.

---

配置

toml [frontmatter] date = [”:filename”, “:default”]


你看,这里 `date` 对应一个数组,`hugo` 会去这个数组,按照元素顺序寻找 `date` 。

在上面的配置里,`hugo` 就优先从文件名("filename")中获取 `date` 。

比如有篇文章命名为 `2018-02-22-mypage.md` ,那么其中的 `2018-02-22` 就会被提取为 `date`。

如果文件名没有 `date`,`hugo` 就从 `:default` 去寻找。(:default 指的啥,以及具体配置请查看文档...)

---

同时,若 `slug` 没有设置,则 `mypage` 会设置为 `slug`。

这里的 `slug` 是个新概念。`slug` 可以在 `front matter` 配置。

### slug

看说明,

> slug:The token to appear in the tail of the URL

这啥玩意...

> 我的理解是:反正看样子这玩意是用来配置 `url` 的,`url` 在哪配置,在 `permalink` 嘛。那这应该是配置 `permalink` 的一个变量。

先不管吧,反正只要我们按照 `year-month-day-title.md` 这样来命名文件,`slug` 在这里显然指的就是 `title`。(虽然 `slug` 的定义应该比这大...)

---

回到 `permalink` 的配置。确实有个 `:slug`。

> `:slug`
>
> the content’s slug (or title if no slug is provided in the front matter)

这里的 `:slug` 就是指 title。

> 看到这,我明白 slug 与 title 的区别了。
>
> 如果我们用标题作文件名,链接也只用标题。
>
> 比如 `post.md`
>
> 解析为
>
> `https://hqweay.cn/post`
>
> 如果文件名冲突咋办?
>
> 这时就可以在 `front matter` 里设置 `slug` 来区分。
>
> 
>
> 另一个问题,文件名怎么会冲突呢?
>
> 前面提到过,在保存博文文件的 `content` 文件夹下可以分文件夹保存博文,不同文件夹下就可能文件名冲突。
>
> 其实如果我们不设置 `permalinks` ,`content` 下若有两个文件夹 `life` ,`study` 。`life` 下有一个 `post.md` 会被渲染为 `https://hqweay.cn/life/post`,`study` 下的 `post.md` 则会被渲染为 `https://hqweay.cn/study/post`。 
>
> 但若设置了 `permalinks` ,链接就不会像这样默认加上子文件夹 `life` 或者 `study` 了。两者都会被渲染为 `https://hqweay.cm/post`,这时,就产生冲突啦!

---

好,配置 `permalinks` 。

toml [permalinks] post = “/:year/:month/:day/:slug/”


结束。

---

### 总结一下

先配置

toml [frontmatter] date = [”:filename”, “:default”]


优先从文件名获取 `date` 。然后把 `title` 解析为 `slug` 。

再通过

toml [permalinks] post = “/:year/:month/:day/:slug/” ```

配置链接解析规则。

此时的 :year:month/:day 就是从文件名获取的 date

:slug 是文件名解析出来的 title