Hugo图片路径处理逻辑

一、问题

最近在更新法规汇编网站的时候遇到一个问题,法规中的图片无法正常显示,网站是基于hugo构建的静态网站,用的hugo-book主题,图片放在markdown文档目录中的images目录下。如下:

DOCS
│
煤矿安全生产类
│
规范性文件
├─ images
│    ├─ image_081.png
│    ├─ image_082.png
│    └─ image_083.png
└─ 煤矿生产能力核定标准.md

图片的正常路径应为:

docs/煤矿安全生产类/规范性文件/images/image_081.png

图片在本地的markdown文档中可以正常显示,但是在md生成的网页上无法正常显示,在网页上查看图片地址发现图片路径为:

docs/煤矿安全生产类/规范性文件/煤矿生产能力核定标准/images/image_081.png

也就是说,根据 hugo 的路径规则,markdown在生成网页后图片多了一层路径煤矿生产能力核定标准,导致图片无法正常显示。

二、解决办法

网上查到的解决方法有两种:

  1. 图片放入 /static 目录下,然后通过绝对路径引入

  2. 将 xxx.md 调整为 xxx/index.md 然后使用相对路径引用图片

但是上述两种方法对我都不太实用,因为涉及到大量的md文档和图片。于是又在网上找到另一种解决方案,通过修改md生成html时图片渲染处理逻辑,以支持相对路径图片引用。具体就是修改 render_image.html (/layouts/_default/_markup/render_image.html),代码如下:

 {{/* 新增逻辑:非 index.md 的本地相对路径添加 ../ */}}
  {{- else -}}
    {{- if and (not (hasPrefix $u.Path "/")) (ne .PageInner.File.LogicalName "index.md") -}}
      {{- $src = printf "../%s" $path -}}
    {{- end -}}
  {{- end -}}
  {{- 一直到这里 -}}

将上述代码放到render_image.html后hugo部署报错,于是求助deepseek,将上述代码和整个render_image.html丢给deepseek并提出要求,deepseek给出render_image.html修改后的结果,完美解决问题,代码如下:

{{- if .Page.Site.Params.BookPortableLinks -}}
  {{- template "portable-image" . -}}
{{- else -}}
  {{- template "portable-image" . -}}
{{- end -}}

{{- define "portable-image" -}}
  {{- $u := urls.Parse .Destination -}}
  {{- $src := $u.String -}}
  
  {{- if not $u.IsAbs -}}
    {{- $path := strings.TrimPrefix "./" $u.Path -}}
    {{- /* 尝试从页面资源或全局资源中获取图片 */ -}}
    {{- with or (.Page.Resources.Get $path) (resources.Get $path) -}}
      {{- $src = .RelPermalink -}}
      {{- with $u.RawQuery -}}
        {{- $src = printf "%s?%s" $src . -}}
      {{- end -}}
      {{- with $u.Fragment -}}
        {{- $src = printf "%s#%s" $src . -}}
      {{- end -}}
    {{- else -}}
      {{- /* 处理非index.md页面的相对路径 */ -}}
      {{- if and (not (hasPrefix $u.Path "/")) (ne .Page.File.LogicalName "index.md") -}}
        {{- $src = printf "../%s" $path -}}
      {{- else -}}
        {{- $src = $path -}}
      {{- end -}}
    {{- end -}}
  {{- end -}}

  {{- /* 创建属性并添加懒加载 */ -}}
  {{- $attributes := dict "alt" .Text "src" $src "loading" "lazy" -}}
  {{- with .Title -}}
    {{- $attributes = merge $attributes (dict "title" (. | transform.HTMLEscape)) -}}
  {{- end -}}
  
  <img
    {{- range $k, $v := $attributes -}}
      {{- if $v -}}
        {{- printf " %s=%q" $k $v | safeHTMLAttr -}}
      {{- end -}}
    {{- end -}}>
{{- end -}}

这个修改后的代码主要包含以下改进:

  1. URL解析:使用urls.Parse正确解析图片目标路径
  2. 资源查找
    • 首先尝试从页面资源中获取图片(适用于页面捆绑)
    • 然后尝试从全局资源中获取
  3. 相对路径处理
    • 对于非index.md的页面,自动添加../前缀来修正路径
    • 保持查询参数和片段标识符
  4. 懒加载:添加了loading="lazy"属性以提高性能
  5. 属性构建:使用更安全的方式构建HTML属性

关键改进点:

  • 使用.Page.File.LogicalName检查当前页面是否为index.md
  • 对于非index.md页面,在相对路径前添加../来适应Hugo的目录结构
  • 保留了查询参数和片段标识符的处理
  • 使用transform.HTMLEscape安全转义title属性

Joker ·
评论 · 首页 订阅