背景:

由于hugo的图片路径渲染方式和obsidian不同 具体表现为: obsidian 是直接从项目根目录的路径开始算,比如:![](static/img/《阿凡达3.火与烬》.webp) 这么写就能在obsidian上查看。

hugo 由于我使用的是 paper-mod,这个主题,它的图片是放在 static/img 路径下,但写的时候就只需要写 img 前缀就可以了,比如:![](/img/《阿凡达3.火与烬》.webp) 但是一旦写成 ![](/img/《阿凡达3.火与烬》.webp) 这种方式,就会导致在obsidian上渲染不出来图片。这两个读取的不一致就会导致图片要不就是只能在 hugo 上面查看,要不就是只能在 obsidian 上面查看,只能二选一,没办法两全其美。

解决方法:

最近问了一下 Gemini,发现可以有解决办法:

在项目根目录的 layouts/_default/_markup/render-image.html 目录下,添加文件: 比如我的目录就是:S:\Hugo\myBlog\layouts\_default\_markup\render-image.html 如果没有该文件,就自己新建一个就好。 新建好文件后,就把下面的代码内容完整地复制剪贴进去,保存一下,然后重启一下Hugo的服务就好

 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
{{- $src := .Destination -}}

{{- /* 1. 去掉 static/ 前缀 */ -}}
{{- if strings.HasPrefix $src "static/" -}}
    {{- $src = strings.TrimPrefix "static/" $src -}}
{{- end -}}

{{- /* 2. 核心修复:确保路径以 / 开头 */ -}}
{{- if not (strings.HasPrefix $src "/") -}}
    {{- $src = printf "/%s" $src -}}
{{- end -}}

{{- /* 3. 处理宽度解析 (支持 ![|80](...) 语法) */ -}}
{{- $alt := .Text -}}
{{- $width := "" -}}
{{- if strings.Contains $alt "|" -}}
    {{- $parts := split $alt "|" -}}
    {{- $alt = index $parts 0 -}}
    {{- $width = index $parts 1 -}}
{{- end -}}

<img loading="lazy" 
     src="{{ $src | safeURL }}" 
     alt="{{ $alt }}" 
     {{ with $width }} width="{{ . }}" {{ end }} 
     {{ with .Title }} title="{{ . }}" {{ end }} />

这个方案的原理是:让 Hugo 在处理图片链接时,如果发现路径是以 static/ 开头的,就自动把 static/ 删掉。这样你在 Obsidian 里能看(因为路径是真的),Hugo 网站也能看(因为生成的 HTML 路径是正确的)。

效果:

  • Obsidian: 依然读取 static/img/xxx.webp,图片显示正常。

  • Hugo: 编译时检测到 static/ 前缀并自动移除,输出给浏览器的地址变成了 /img/xxx.webp,图片显示正常。