本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2020年11月08日 统计字数: 5690字 阅读时间: 12分钟阅读 本文链接: https://soulteary.com/2020/11/08/upgrade-hugo-across-versions-2.html ----- # Hugo 跨版本升级(二) 上一次折腾 Hugo 是[去年年初的](https://soulteary.com/2019/02/01/upgrade-hugo-across-versions.html)事情了,时隔接近两年,再次记录下 Hugo 跨版本升级的一些实践细节。 ## 写在前面 为什么接近两年时间里,没有继续折腾 Hugo 呢? 1. 我对网站模版功能没有变动诉求。这个模版虽然写于六年前,但是不论性能还是基础功能、以及在资源有限的老设备上运行,都没有什么问题。在三年前移植到 Hugo 模版后,除了为增强 Hugo 日志归档功能,添加了一个功能外,就没有变动了。 2. Hugo 跨版本升级,总会出现一些 Break Changes 的问题。在 0.5x 版本和 0.6x 版本中,官网引入了一些导致 Crash 的问题,让我没有升级的兴趣。 那为什么有了这篇文章呢?主要也有两个原因: 1. 最近业务上有静态网站诉求,使用 Hugo 0.78 构建了一个站点,目测后续还有更多的需求,所以需要深度使用踩踩坑。相比较零到一的站点,我的网站有上千篇内容,以及各种场景站点的模块,作为试验田非常合适。 2. 为了统一软件技术栈,减少维护心智负担,只要新版本的软件在数据和功能处理方面没有问题,我一般会将其升级到新的稳定版本。 ## 主要调整内容 因为之前使用 Hugo 模版功能,将一些场景的功能模块,以及这几个版本中 Hugo 变动了的接口都实现和封装了一遍,比如:页面布局模块、RSS、归档页面、多级文档目录、网站地图... 所以这里升级只需要调整一些简单的数据字段引用,或者调整下配置文件,最多是调整下 Nginx 配置,除了调试编写模版外,过程还是比较轻松的。 ### 修正路由变化的独立页面 在升级到 0.78 之后,Hugo 配置文件中的 `uglyurls = true` 配置项会使得独立的页面路由发生一些变化,从原来的 `/pageName` 变为 `/pageName.html` 。 如果你想让页面 URL 保持和原来一致,可以考虑参考 [内容组织管理](https://gohugo.io/content-management/organization/#url-1) 文档中的方案,在 Markdown 文档中添加下面的参数来声明页面的地址。 ```Toml url = /page-url/ ``` ### 部分模版使用 Page 变量获取数据为空 在升级之后,有一部分模版页面使用 `where` 函数获取站点数据会出现异常。 ```html {{ $Posts := where .Pages "Section" "post" }} {{ range $Posts }}
{{.Title}}
{{end}} ``` 这时可以尝试使用带有 `$.Site` 命名空间,或者更换方法为 `RegularPages` 来获取数据。 ```html {{ $Posts := where $.Site.Pages "Section" "post" }} {{ range $Posts }}{{.Title}}
{{end}} {{ $Posts := where .RegularPages "Section" "post" }} {{ range $Posts }}{{.Title}}
{{end}} ``` ### 标签分类地址兼容 [上篇文章中](https://soulteary.com/2019/02/01/upgrade-hugo-across-versions.html)有提过对一些带有特殊符号的标签,做了 URL 兼容,避免它生成多级目录。 官方对于标签/分类的 URL 生成其实一直很摇摆,挨着时间顺序看以下讨论,可以发现官方原本的方向是朝着标准的网站实现去做的: - [https://github.com/gohugoio/hugo/issues/3577](https://github.com/gohugoio/hugo/issues/3577) - [https://github.com/gohugoio/hugo/issues/4090](https://github.com/gohugoio/hugo/issues/4090) - [https://github.com/gohugoio/hugo/pull/5519/files](https://github.com/gohugoio/hugo/pull/5519/files) - [https://github.com/gohugoio/hugo/pull/5282](https://github.com/gohugoio/hugo/pull/5282) 但是在有一天,一个老外反馈他使用 Hugo 做地理位置多级联动的站点,官方便对上面的实现方案产生了动摇,最终将 Hugo 的标签生成模式改成了下面这样: - [https://github.com/gohugoio/hugo/issues/5571](https://github.com/gohugoio/hugo/issues/5571) 并且单独开了一个帖子,讨论未来如何增强调整标签/分类的地址: - [https://github.com/gohugoio/hugo/issues/5520](https://github.com/gohugoio/hugo/issues/5520) 为了不"伤经动骨",单独编译一个定制版出来。这里可以使用 Nginx 处理链接兼容问题,让原来的 `/tags/linux-mac.mac` 这类只有两级目录的标签/分类转向到类似 `/tags/linux/mac.html`的地址。 ```c location = /tags/linux-mac.html { return 301 https://$host/tags/linux/mac.html; } location ~* ^/tags/linux-mac/(page/.*)$ { return 301 https://$host/tags/linux/mac/$1; } ``` ### 使用自定义模版输出 RSS [上篇文章中](https://soulteary.com/2019/02/01/upgrade-hugo-across-versions.html)我有提过我使用自定义的模版替换了官方实现的 RSS 生成,所以在官方修改 RSS 输出实现后,也就幸免,省的折腾了。 ### 调整客户端输出页面为服务端 之前生成日志归档,主要依赖前端脚本和 Hugo 模版,以及脚本生成的列表数据进行页面生成。 比如先使用工具生成类似下面年份或者月份的内容: ```md --- title: "2020年文章存档" type: archives draft: false isCJKLanguage: true outputs: [ "HTML"] --- ## [2020年11月](/archives/2020/11/) - `01` [使用 Nginx 构建前端日志统计服务(打点采集)服务](/2020/11/01/use-nginx-to-build-a-front-end-log-statistics-service-service.html) ## [2020年10月](/archives/2020/10/) - `31` [阿里云 IP 地理位置库(淘宝IP库)实践(后篇)](/2020/10/31/dockerize-aliyun-geoip-part-2.html) - `30` [阿里云 IP 地理位置库(淘宝IP库)实践(前篇)](/2020/10/30/dockerize-aliyun-geoip-part-1.html) - `04` [容器化 FRP 使用方案](/2020/10/04/frp-in-docker.html) ... ``` Hugo 模版调整为方便 JavaScript 使用的模式就行,将上面的内容,直接输出在页面中: ```html' + data.desc + '
'); tpl.push('