hexo迁移hugo解决图片路径问题插件

摘要: hexo迁移hugo解决图片路径问题插件(通过豆包AI生成)


先说解决办法

新建文件

1
2

\layouts\_default\_markup\render-image.html

文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{{- /* 图片渲染钩子 - 为所有相对路径图片添加文章目录前缀 */ -}}

{{- $fileDir := replace (.Page.File.Dir | default "") "\\" "/" -}}
{{- $articleDir := strings.TrimSuffix "/" (strings.TrimPrefix "content/" $fileDir) }}
{{- $src := .Destination -}}

{{- if not (or (hasPrefix $src "http://") (hasPrefix $src "https://") (hasPrefix $src "/")) -}}
{{- if eq $articleDir "" -}}
{{- $src = printf "/%s" $src -}}
{{- else -}}
{{- $src = printf "/%s/%s" $articleDir $src -}}
{{- end -}}
{{- end -}}

<img
src="{{ $src }}"
alt="{{ .Text | safeHTML }}"
{{ with .Title }}title="{{ . | safeHTML }}"{{ end }}
loading="lazy"
>

调试版本文件内容,正常用上边的即可

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
{{- /* 图片渲染钩子 - 为所有相对路径图片添加文章目录前缀 */ -}}

{{- /* 获取当前页面和文件信息 */ -}}
{{- $page := .Page -}}
{{- $fileDir := $page.File.Dir | default "" -}}

{{- /* 将文件目录转换为正斜杠格式并移除content/前缀 */ -}}
{{- $normalizedDir := replace $fileDir "\\" "/" -}}
{{- $articleDir := strings.TrimPrefix "content/" $normalizedDir -}}
{{- $articleDir = strings.TrimSuffix "/" $articleDir -}} {{/* 移除末尾斜杠 */ -}}

{{- /* 获取原始图片路径 */ -}}
{{- $src := .Destination -}}
{{- $isRelative := not (or (hasPrefix $src "http://") (hasPrefix $src "https://") (hasPrefix $src "/")) -}}

{{- /* 如果是相对路径,则添加文章目录前缀 */ -}}
{{- if $isRelative -}}
{{- if eq $articleDir "" -}}
{{- $src = printf "/%s" $src -}} {{/* 如果文章目录为空,添加根路径前缀 */ -}}
{{- else -}}
{{- $src = printf "/%s/%s" $articleDir $src -}} {{/* 添加文章目录前缀 */ -}}
{{- end -}}
{{- end -}}

{{- /* 开发环境显示调试信息 */ -}}
{{- if eq hugo.Environment "development" -}}
<div style="background:#f8f8f8; padding:10px; margin:10px 0; border:1px solid #eee; font-size:12px;">
<p><strong>图片路径调试信息</strong></p>
<p>文章目录: <code>{{ $articleDir }}</code></p>
<p>原始路径: <code>{{ .Destination }}</code></p>
<p>是否相对路径: <code>{{ $isRelative }}</code></p>
<p>处理后路径: <code>{{ $src }}</code></p>
</div>
{{- end -}}

<img
src="{{ $src }}"
alt="{{ .Text | safeHTML }}"
{{ with .Title }}title="{{ . | safeHTML }}"{{ end }}
loading="lazy"
>

说明

只处理相对路径

  1. 图片路径是相对路径(即不以 /http://https:// 开头)

  2. 自动为图片路径添加 /文章目录/ 前缀。

图片引用写法

图片建议放在同名子目录下 hexo就是这样,也可以和md文件放在一起

代码说明(豆包生成)

代码详解:Hugo 图片渲染钩子

这个渲染钩子的核心功能是根据文章所在目录,自动为相对路径的图片添加对应前缀。以下是对代码的详细拆解:

1. 获取文章目录信息

1
2
{{- $fileDir := replace (.Page.File.Dir | default "") "\\" "/" -}}
{{- $articleDir := strings.TrimSuffix "/" (strings.TrimPrefix "content/" $fileDir) }}
  • $fileDir
    
    1
    2
    3
    4
    5

    :获取当前文章的文件目录路径(如



    content/post/2025/06/
    1
    2
    3
    4
    5
    6
    7



    - `replace ... "\\" "/"`:将 Windows 路径分隔符 `\` 转换为 Unix 格式 `/`

    - ```
    $articleDir
    :处理后的目录路径(如
    1
    post/2025/06
    ) - `strings.TrimPrefix "content/"`:移除 `content/` 前缀 - `strings.TrimSuffix "/"`:移除末尾的斜杠

2. 判断图片路径类型

1
2
3
4
{{- $src := .Destination -}}
{{- if not (or (hasPrefix $src "http://") (hasPrefix $src "https://") (hasPrefix $src "/")) -}}
{{- /* 相对路径处理逻辑 */ -}}
{{- end -}}
  • $src:原始图片路径(如 images/logo.png
  • 判断条件
    若路径不以 http://https:/// 开头,则视为相对路径

3. 添加目录前缀

1
2
3
4
5
{{- if eq $articleDir "" -}}
{{- $src = printf "/%s" $src -}}
{{- else -}}
{{- $src = printf "/%s/%s" $articleDir $src -}}
{{- end -}}
  • 逻辑分支

    1. 若文章位于 content/ 根目录$articleDir 为空):
      直接添加根路径前缀 /(如 logo.jpg/logo.jpg
    2. 若文章位于子目录(如 content/post/2025/):
      添加完整目录前缀(如 images/logo.png/post/2025/images/logo.png

4. 完整渲染钩子代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{{- /* 图片渲染钩子 - 为所有相对路径图片添加文章目录前缀 */ -}}

{{- $fileDir := replace (.Page.File.Dir | default "") "\\" "/" -}}
{{- $articleDir := strings.TrimSuffix "/" (strings.TrimPrefix "content/" $fileDir) }}
{{- $src := .Destination -}}

{{- if not (or (hasPrefix $src "http://") (hasPrefix $src "https://") (hasPrefix $src "/")) -}}
{{- if eq $articleDir "" -}}
{{- $src = printf "/%s" $src -}}
{{- else -}}
{{- $src = printf "/%s/%s" $articleDir $src -}}
{{- end -}}
{{- end -}}

<img
src="{{ $src }}"
alt="{{ .Text | safeHTML }}"
{{ with .Title }}title="{{ . | safeHTML }}"{{ end }}
loading="lazy"
>

执行流程示例

场景 1:文章位于 content/post/2025/06/

  • Markdown 图片路径images/logo.png

  • 处理过程

    1. $articleDirpost/2025/06
    2. 路径拼接 → /post/2025/06/images/logo.png
  • 渲染结果

    1
    <img src="/post/2025/06/images/logo.png" alt="Logo" loading="lazy">

场景 2:文章位于 content/ 根目录

  • Markdown 图片路径favicon.ico

  • 处理过程

    1. $articleDir → 空字符串
    2. 路径拼接 → /favicon.ico
  • 渲染结果

    1
    <img src="/favicon.ico" alt="Favicon" loading="lazy">

场景 3:绝对路径图片

  • Markdown 图片路径/static/banner.jpg

  • 处理过程

    1. 判断为绝对路径 → 直接跳过处理
  • 渲染结果

    1
    <img src="/static/banner.jpg" alt="Banner" loading="lazy">

核心优势

  1. 自动化路径管理
    • 无需手动维护图片路径前缀,减少错误
    • 文章移动时,图片路径自动更新
  2. 跨平台兼容性
    • 统一处理 Windows 和 Unix 路径格式
  3. 灵活性
    • 适用于任何目录结构(不限于 post/
    • 支持多级子目录(如 category/subcategory/

调试与故障排除

在开发环境中,可通过以下方式验证:

  1. 启用调试信息

    bash

    1
    hugo server --environment development
  2. 检查调试输出

    plaintext

    1
    2
    3
    4
    5
    图片路径调试信息
    文章目录: post/2025/06
    原始路径: images/logo.png
    是否相对路径: true
    处理后路径: /post/2025/06/images/logo.png
  3. 常见问题

    • 图片不显示:检查 $articleDir 是否正确提取
    • 路径未添加前缀:确认图片路径是否为相对路径

通过配置的方式增加前缀代码备份

需要在主配置文件,增加配置

1
2
params: 
cdnURL: http://test.com

最终版

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{{- /* 图片渲染钩子 - 添加CDN前缀 */ -}}

{{- /* 获取全局站点对象 */ -}}
{{- $site := site -}}

{{- /* 获取CDN配置 */ -}}
{{- $cdn := $site.Params.cdnURL | default "" -}}

{{- /* 获取原始图片路径 */ -}}
{{- $src := .Destination -}}

{{- /* 处理路径 */ -}}
{{- if and (ne $cdn "") (not (or (hasPrefix $src "http://") (hasPrefix $src "https://"))) -}}
{{- $src = printf "%s/%s" $cdn (strings.TrimPrefix "/" $src) -}}
{{- end -}}

<img
src="{{ $src }}"
alt="{{ .Text | safeHTML }}"
{{ with .Title }}title="{{ . | safeHTML }}"{{ end }}
loading="lazy"
>

调试版

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
{{- /* 图片渲染钩子 - 添加CDN前缀 */ -}}

{{- /* 获取全局站点对象 */ -}}
{{- $site := site -}}

{{- /* 获取CDN配置 */ -}}
{{- $cdn := $site.Params.cdnURL | default "" -}}
{{- if eq $cdn "" -}}
{{- warnf "CDN prefix not set in config_default/hugo.yaml" -}}
{{- end -}}

{{- /* 获取原始图片路径 */ -}}
{{- $src := .Destination -}}

{{- /* 判断是否为开发环境 */ -}}
{{- $isDev := eq hugo.Environment "development" -}}

{{- /* 调试输出 (仅在开发环境) */ -}}
{{- if $isDev -}}
<div style="background:#f8f8f8; padding:10px; margin:10px 0; border:1px solid #eee;">
<p><strong>Image Debug:</strong></p>
<p>Original: <code>{{ $src }}</code></p>
<p>CDN: <code>{{ $cdn }}</code></p>
{{- if and (ne $cdn "") (not (or (hasPrefix $src "http://") (hasPrefix $src "https://"))) -}}
<p>Processed: <code>{{ printf "%s/%s" $cdn (strings.TrimPrefix "/" $src) }}</code></p>
{{- end -}}
</div>
{{- end -}}

{{- /* 处理路径 */ -}}
{{- if and (ne $cdn "") (not (or (hasPrefix $src "http://") (hasPrefix $src "https://"))) -}}
{{- $src = printf "%s/%s" $cdn (strings.TrimPrefix "/" $src) -}}
{{- end -}}

<img
src="{{ $src }}"
alt="{{ .Text | safeHTML }}"
{{ with .Title }}title="{{ . | safeHTML }}"{{ end }}
loading="lazy"
>