Hugo 短代码实践:bundle-file(多语言文件和附件放在同一个 Page Bundle 目录中)

使用自定义 bundle-file 短代码,在当前语言资源缺失时自动回退到其他翻译页面,统一输出附件下载链接。

在多语言站点中,文章正文通常会有同一份附件(例如 PDF、配置文件、脚本)。 如果每个语言版本都手工维护下载链接,后期很容易出现链接不一致或文件丢失。

这篇文章给出一个可直接复用的 Hugo 短代码 bundle-file,用于解决这个问题。

目标

将同一篇文章的多语言文件和附件放在同一个 Page Bundle 目录中,例如:

1
2
3
4
5
6
content/post/2026/03/09/01/
  index.zh-cn.md
  index.zh-tw.md
  index.en.md
  demo.pdf
  script.sh

这样可以最大化复用资源,减少重复拷贝。 hugo转换成html后,希望多个语言指向相同的一份附件,不重复拷贝。

短代码实现

文件:layouts/shortcodes/bundle-file.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{{- $name := .Get "name" -}}
{{- $text := .Get "text" | default $name -}}

{{- $res := .Page.Resources.GetMatch $name -}}
{{- if not $res -}}
  {{- range .Page.AllTranslations -}}
    {{- if not $res -}}
      {{- $tmp := .Resources.GetMatch $name -}}
      {{- if $tmp }}{{ $res = $tmp }}{{ end -}}
    {{- end -}}
  {{- end -}}
{{- end -}}

{{- if $res -}}
<a href="{{ $res.RelPermalink }}">{{ $text }}</a>
{{- else -}}
<span>Missing file: {{ $name }}</span>
{{- end -}}

bundle-file 的行为很简单:

  1. 优先从当前页面的资源里查找文件。
  2. 当前语言找不到时,到其他翻译页面继续查找同名文件。
  3. 找到后输出下载链接,找不到时提示缺失文件名。

参数说明

  • name:附件文件名,必填。
  • text:链接展示文本,可选;不传时默认显示 name

使用示例

1
Missing file: demo.pdf

不传 text 时:

1
Missing file: demo.pdf

发布前检查

  1. 附件与文章位于同一个 Page Bundle。
  2. name 与真实文件名完全一致(含大小写)。
  3. 本地预览点击链接,确认可访问。

总结

bundle-file 让多语言文章的附件链接管理从“手工维护路径”,变成“按规则自动查找”。 对长期维护的知识库或技术博客来说,这能显著降低链接错误率,也能减少发布前排查成本。

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计