官方给了简明的快速上手教程,但是稍微挖深一点就会不那么简单了。本地资源相对路径和theme管理这两个东西,花费了一些功夫大概算是解决了。

本地资源相对路径

Hugo生成静态网页的时候,会将static目录下的内容复制到发布目录中,这个机制在发布和预览上会产生矛盾。编辑器一般会按Hugo的工程目录来找资源,图片假如放在static/images里头,然后用/images来引用,发布时路径有效,但在撰写的时候没法看到带图的预览。如果把资源放在static里头且能预览,编辑器就要用/static/images的路径,但在发布时static没有了,路径失效。可以用Hugo的union-file-system来解决这个矛盾。将images放在Hugo工程根目录下,然后把这个目录映射到static里去,就像这样:

[module]
  [[module.mounts]]
    source = 'images'
    target = 'static/images'

在编写的时候使用相对路径引用,比如某个页面是content/posts/xxx.md,用../../images/xxx.jpg引用资源,编辑器里可以预览。发布的页面路径是posts/xxx/index.html,这时../../images/xxx.jpg路径保持有效。不过这样做有那么一点不太优雅,如果资源类型多,就需要在工程目录下放一堆文件夹…

theme管理

Hugo新手教程用gitmodule管理theme。这种玩法theme默认不会被加入主仓库,所以用钩子脚本在远程仓库checkout出来没有theme。但如果尝试git submodule update --init --recursive,会发现因为远程仓库大多为裸仓库,没有work tree,所以执行不了。解决办法可以是把远程仓库弄成个普通仓库,不过这样的远程仓库默认禁止被推,需要在远程仓库的config文件中加入以下内容。

[receive]
    denyCurrentBranch = ignore

这个方法有点不够优雅。所以改用比较顺眼的mod功能来管理(参考1参考2),大概意思就是仿照go mod的套路,先给工程加个go.mod开启模块功能,然后下载对应的模块,然后把主题指定到这个模块。hugo的mod实际上应该就是借用go的mod,所以需要远程端装个go。主要步骤如下,第一句应该也和go mod init一样一定要给个工程名字,但不一定非要写成这个样子。

hugo mod init YOUR_DOMAIN/YOUR_USERNAME/YOUR_PROJECT
hugo mod get github.com/adityatelange/hugo-PaperMod
hugo mod tidy

然后在工程配置文件里加上模块信息。

theme = 'github.com/adityatelange/hugo-PaperMod'

[module]
  [[module.imports]]
    path = "github.com/adityatelange/hugo-PaperMod"

下面这段脚本放在远程仓库的hooks目录的post-receive里,每次推完就能自动的更新发布。

#!/bin/bash

# 签出到某个工作文件夹,一定要加这个GIT_WORK_TREE
GIT_WORK_TREE=/you/temp/path/ git --git-dir=/your/git/path checkout -f
# 更新一下主题(可选)
hugo mod get -u

hugo -s /you/temp/path/ -d /you/public/path/