在各个静态博客网站生成工具之间迁移文章时,可能会遇到链接不一致的问题。
比如你在 jekyll
配置好了,文章链接是 https://hqweay.cn/2019/09/23/new-post
。迁移到 hexo
,文章链接就变成了 https://hqweay.cn/2019/09/23/2019-09-23-new-post
。
通常,为了 SEO、使用第三方评论、或其它原因,我们总希望博客迁移后,链接保持能不变。这里讨论一下我使用 jekyll
、hexo
、hugo
在迁移数据时的一些感想。
先给一下方案,我建议文章按照 year-month-day-title.md
,即 年-月-日-标题.md
的格式命名。比如 2019-09-22-new-post.md
。之所以建议这样命名,是因为 jekyll
要求文章的文件名必须遵循这种格式。而 hexo
与 hugo
则没有这样的要求,后两者默认 文件名 作为标题。
以这种方式命名,hexo
与 hugo
仍可以通过配置获取到真正的 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
这样的链接也行。不过把时间区分出来观感好点…
给出方式。
文件名 :year-month-day-title.md
配置文件 _config.yml
添加
permalink : /:year/:month/:title
文件名 :year-month-day-title.md
配置文件 config.yml
添加
new_post_name: :year-:month-:day-:title.md
permalink: :year/:month/:day/:title/
文件名 :year-month-day-title.md
配置文件 config.toml
[frontmatter]
date = [":filename", ":default"]
[permalinks]
post = "/:year/:month/:day/:slug/"
这里先提一下,post = "/:year/:month/:slug/"
这条配置规则指的是 hugo
的 content
文件夹下的 post
文件夹下的文章都用这条规则来解析。
如果 content
文件夹下还有其它文件夹,则其它文件夹下的文章的链接解析不受此规则影响。
比如 content
下有 study
和 life
两个文件夹,则两者都需要配置上。
如
[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
这个属性来配置链接的生成规则。permalink
是Permanent 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
后缀。
具体配置方式比较多,详见官方文档。
hexo
与 jekyll
的不同之处在于,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/
。
不对劲吧。
这就是因为在 hexo
的 permalink
里,默认的 :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
,就是为了把文件名中的 year
、month
等取为 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/2019-09-23-new-post/
了。
hugo
和 hexo
类似,默认以文件名作为 title
。
即便我们没使用过 hugo
,也可以畅想一下,hugo
里有没有这样的配置?
一:配置解析链接的规则。
二:从文件名提取真正的 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 filecontent/posts/sample-entry.md
withdate: 2017-02-27T19:20:00-05:00
in its front matter will render topublic/2017/02/sample-entry/index.html
at build time and therefore be reachable athttps://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/
访问。
这样可以配置解析链接的规则,但同时也如文档所说,此时使用的 date
是 front matter
里定义的,而且 title
是文件名。
瞧瞧 front matter
…
---
title: "快乐星猫"
date: 2019-09-23T23:00:01+08:00
draft: true
---
注意!
默认生成的文章 date
使用的时间格式是 YYYY-MM-DD HH:MM:SS +0800
。
格式不作说明了。
没看文档,网上资料说时间格式必须这样。从 hexo
迁移到 hugo
,也需要注意这个,把时间修改一下。
但是我貌似没修改也渲染出来了…
不过我现在不打算折腾 hugo,这个疑问先留着吧…
那有没有解析文件名的配置呢?
这里~
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 date2018-02-22
. Also, ifslug
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 parametersdate
,publishDate
and lastlylastmod
.
配置
[frontmatter]
date = [":filename", ":default"]
你看,这里 date
对应一个数组,hugo
会去这个数组,按照顺序寻找 date
。
在这里,hugo
就优先从文件名中获取 date
。
比如有篇文章命名为 2018-02-22-mypage.md
,那么其中的 2018-02-22
就会被提取为 date
。
如果文件名没有时间,就从 :default
去寻找。(具体看文档…)
同时,若 slug
没有设置,则 mypage
会设置为 slug
。
这里的 slug
是个新概念。slug
可以在 front matter
配置。
看说明,
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
。其实post.md
链接会渲染为https://hqweay.cn/life/post
。但若设置了
permalinks
,链接就不会像这样默认加上子文件夹life
了…
好,配置 permalinks
。
[permalinks]
post = "/:year/:month/:day/:slug/"
ojbk。
总结一下。
先配置
[frontmatter]
date = [":filename", ":default"]
优先从文件名获取 date
。然后把 title
解析为 slug
。
再通过
[permalinks]
post = "/:year/:month/:day/:slug/"
配置链接解析规则。
此时的 :year
、:month
、/:day
就是从文件名获取的 date
。
:slug
是文件名解析出来的 title
。