PS
[update-2020-07-12]:我自己又读了一遍,发现前面的配置还有可取之处,但是后面的说明实在是逻辑混乱胡说八道。看到这篇文章的朋友请酌情阅读。
说明
在各个静态博客网站生成工具之间迁移文章时,可能会遇到链接不一致的问题。
比如你在 jekyll
配置好了,文章链接是 https://leay.net/2019/09/23/new-post
。迁移到 hexo
,文章链接又变成了 https://leay.net/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://leay.net/2019/09/23/new-post
。
如果只用 title
作为链接,比如 https://leay.net/new-post
,若两篇文章 title
一样的话,就 可能 会冲突。用年、月、日、标题确定唯一的文章,就很难冲突啦。
这点和上面文件夹命名同理。
其实只是为了不冲突,https://leay.net/2019-09-23-new-post
这样的链接也行。不过把时间区分出来观感好点……
给出方式。
如何配置
jekyll
文件名 :year-month-day-title.md
配置文件 _config.yml
添加
1 | permalink : /:year/:month/:title |
hexo
文件名 :year-month-day-title.md
配置文件 config.yml
添加
1 | new_post_name: :year-:month-:day-:title.md |
hugo
文件名 :year-month-day-title.md
配置文件 config.toml
1 | [frontmatter] |
这里先提一下,post = "/:year/:month/:slug/"
这条配置规则指的是 hugo
的 content
文件夹下的 post
文件夹下的文章都用这条规则来解析。
如果 content
文件夹下还有其它文件夹,则其它文件夹下的文章的链接解析不受此规则影响。
比如 content
下有 study
和 life
两个文件夹,则两者都需要配置上。
如
1 | [frontmatter] |
为啥呢?
说明
先提一下,现在手上没有 jekyll
环境,也没看过源代码,以下都是我的猜测理解……
一般的静态网页生成工具都提供文件名与链接地址的映射。
比如文件名为 2019-09-23-new-post.md
,若生成静态页面且部署后,访问的链接可能是这样的。
https://leay.net/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://leay.net/2019/09/23/new-post.html
。
——注意,上面这样配置,会跟上后缀 .html
。
若配置为 permalink : /:year/:month/:title
,链接则解析为 https://leay.net/2019/09/23/new-post
。
没有 .html
后缀。
具体配置方式比较多,详见官方文档。
从 jekyll 迁移至 hexo
hexo
与 jekyll
的不同之处在于,hexo 可以取博文在 Front Matter 中定义的时间 。
写文章时常常有这样的内容。
1 | --- |
---
中间那一坨就是 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://leay.net/2019/09/23/2019-09-23-new-post/
。
不对劲吧。
这就是因为在 hexo
的 permalink
里,默认的 :year
,:month
等使用的是 front matter 里的 date 。
我们分析下链接 http://leay.net/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://leay.net/2019/09/23/new-post/
了。
从 hexo 迁移至 hugo
hugo
和 hexo
类似,默认以文件名作为 title
。
即便我们没使用过 hugo
,也可以畅想一下,hugo
里有没有类似 hexo
这样的配置?
一:配置解析链接的规则。
二:从文件名提取真正的 title
。
带着疑问查看文档。
permalinks
首先看到了 permalinks
的配置。
https://gohugo.io/content-management/urls/#permalinks
1 | [permalinks] |
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
是文件名。
瞧瞧 hugo 文件的 front matter
瞧瞧 front matter
……
1 | --- |
注意!默认生成的文章中,
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 date2018-02-22
. Also, ifslug
is not set,mypage
will be used as the value for.Slug
.An example:
1
2 [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
.
配置
1 | [frontmatter] |
你看,这里 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。
好,配置 permalinks
吧。
1 | [permalinks] |
结束。
那 :slug 与 title 的区别是啥?
如果我们用标题作文件名,链接也只会使用标题。
比如 post.md
会解析为 https://leay.net/post
。
如果文件名冲突咋办?
这时就可以在 front matter
里设置 slug
来区分。
另一个问题,文件名怎么会冲突呢?
前面提到过,在保存博文文件的 content
文件夹下可以分文件夹保存博文,不同文件夹下就可能文件名冲突。
其实如果我们不设置 permalinks
,content
下若有两个文件夹 life
,study
。
– /content
---- /life
------ post.md
---- /study
------ post.md
life
下有一个 post.md
会被渲染为 https://leay.net/life/post
,study
下的 post.md
则会被渲染为 https://leay.net/study/post
。
但若设置了 permalinks
,链接就不会像这样默认加上子文件夹 life
或者 study
了。两者都会被渲染为 https://leay.net/post
,这时,就产生冲突啦!
总结一下
先配置
1 | [frontmatter] |
优先从文件名获取 date
。然后把 title
解析为 slug
。
再通过
1 | [permalinks] |
配置链接解析规则。
此时的 :year
、:month
、/:day
就是从文件名获取的 date
。
:slug
是从文件名解析出来的 title
。