Hugo 网站优化(1): 渲染 Markdown 图片引用地址

大家好, 我是老麦 欢迎 关注公众号 maitalking订阅网站 https://tangx.in/ 。 第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「在看」,感谢支持。

作为一个技术人员, 使用 Markdown 写文章确实很方便。

引用图片通常有如下三种

1
2
3
4
5
6
7
8
9
# 1. 相对路径
![](image.png)   # 本文不讨论
![](./image.png)

# 2. 工程目录绝对路径
![](/static/logo/image.png) 

# 3. 外部引用
![](http://example.com/logo/image.png) 

但如果通过 hugo, jekyll 等引擎编译后,

相对路径: 由于 my-post.md 文件被编译成 my-post/index.html。 最终网站静态目录如下

.
├── image.png
└── my-post
    └── index.html

工程目录绝对路径/static 是一个关键字, 其子文件在编译后, 才存在于 一级 目录

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
## 编译前
.
└── static
    └── logo
        └── avatar.png

## 编译后
public  # 网站目录
└── logo # 一级目录
    └── avatar.png

1. 相对路径2. 工程目录绝对路径 通常会出现渲染后的路径错误。

优化渲染 Markdown 图片引用地址

一切为了保证 原始文件 markdown 本身展示图片可用。

决定在渲染模版中,做一些逻辑判断操作。

Hugo 配置如下

config.toml 中新增如下两个配置文件

1
2
3
4
5
6
7
8
9
# 去除工程目录 prefix 文件路径
[params.static_prefix]
    name = "/static"

# 外部 CDN 加速图片, 将图片地址替换成外部前缀
[params.image_cdn]
    enable = false 
    host = "https://cdn.example.com
    # host = "https://cdn.jsdelivr.net/gh/user/user.github.io"

render-image.html 文件优化如下

渲染逻辑如下。

  1. 通过 .Destination 拿到图片在 markdown 中的地址, 并保存在变量 $img_dest
  2. 判断 static_prefix 参数是否设置。
    1. : 去除 $img_dest 中的 prefix
  3. 相对路径 修改为 绝对路径
    1. 这里以 ./ 作为相对路径的 关键字 进行判断。
    2. 因此优化操作不能识别 image.png../image.png 这两种形式。 需要要求个人书写习惯。
  4. 判断 image_cdn 是否设置。
    1. : 在 绝对路径 前添加 外部 CDN 地址
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<!-- 1. 变量赋值 -->
<!-- 1.1. 默认情况, 获取图片的定义地址 -->
<!-- ./image.png -->
<!-- /static/img/image.png -->
<!-- http://example.com/path/to/image.png -->
{{- $img_dest := .Destination -}}

<!-- 1.2. 网站 BaseURL 与 文件相对路径 -->
{{- $site_url := .Page.Site.BaseURL -}}
{{- $rel_url := $site_url | relURL}}

<!-- 2. 去除 prefix, 并添加 **没有域名的 BaseURL ** -->
{{ if and (isset .Page.Site.Params "static_prefix") }}
{{ $prefix := .Page.Site.Params.static_prefix.name }}
<!-- img_dest = /prefix/static/image.png -->
{{ if (hasPrefix $img_dest $prefix )}}
<!-- img_dest = /static/image.png -->
{{ $img_dest = (strings.TrimPrefix $prefix $img_dest ) }}
<!-- img_dest = /path/to/static/image.png -->
{{ $img_dest = (print (path.Join $rel_url $img_dest))}}
{{ end }}
{{ end }}

<!-- 3. 计算文件绝对路径 -->
<!-- dest = ./image.png -->
{{ if (hasPrefix $img_dest "./") }}
<!-- img_dest = .././image.png -->
{{ $img_dest = (print "../" (path.Join $img_dest)) }}
<!-- img_dest = /posts/<year>/<month>/<date>/<post_name>/.././image.png -->
{{ $img_dest = (print (path.Join .Page.RelPermalink $img_dest))}}
{{ end }}


<!-- 4.  开启 CDN -->
<!-- 是否开启 CDN 选项 -->
{{- if (and .Page.Site.Params.image_cdn.enable (not .Page.Site.IsServer)) -}}
<!-- 文件不以 http 开头 -->
{{ if not (hasPrefix $img_dest "http") }}
<!-- image_cdn + /path/to/image.png -->
{{ $img_dest = (print .Page.Site.Params.image_cdn.host (path.Join $img_dest)) }}
{{ end }}
{{- end -}}
<!-- CDN END -->


<img 
    src="{{ $img_dest | safeURL }}" 
    alt="{{ .Text }}" 
    {{ with .Title }} 
        title="{{ . }}" 
    {{ end }} 
/>
{{- /* Drop trailing newlines */ -}}

被玩崩了的 jsdelivr CDN

jsdelivr CDN 已经被玩坏了。

对于 github 个人用户的资源加速已经, 目前只能在国外有效。 国内 IP 访问, 将被重定向到 github raw 页面, 然而这个地址被墙了, 无法访问。