При создании мультиязычного контента на Hugo возникла проблема - на основном языке картинки в статье отображаются нормально, а при переключении языка на дополнительный, картинки перестают отображаться.
Все картинки хранятся в той же папке где и сам markdown файл со статьей.
Hugo экспортирует статьи в такую структуру. Видно что все картинки хранятся в папке с основным языком (папка hugo-obsidian
), а в папке с языком en
картинок нет, что правильно, потому что их не нужно дублировать.
├── en
│ ├── hugo-obsidian
│ │ └── index.html
├── hugo-obsidian
│ ├── 1.png
│ ├── 10.mp4
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ ├── 5.png
│ ├── 6.png
│ ├── 7.png
│ ├── 8.png
│ ├── 9.png
│ └── index.html
При отображении статьи на основном языке, путь до картинки относительный. То есть при открытии статьи /hugo-obsidian/
все картинки будут отображаться, потому что они лежат в этой папке.
<img loading="lazy" src="4.png" alt="Зашифрованные файлы">
При отображении статьи на дополнительном языке, путь до картинки тоже относительный. То есть при открытии статьи /en/hugo-obsidian/
, картинки буду пытаться открыться из этой же папки, а их там нет.
<img loading="lazy" src="4.png" alt="Encrypted files">
В результате получаю ошибки что файлы не найдены.
Нужно сделать так чтобы в статье на дополнительном языке картинки открывались из папки основного языка. Для этого нужно изменить рендер картинок. Для этого в Hugo есть render hooks
Нужно создать файл layouts/_default/_markup/render-image.html
с таким кодом:
{{- $alt := .Text | safeHTML }}
{{- $title := .Title | safeHTML }}
{{- $src := "" }}
{{- $u := urls.Parse .Destination }}
{{- if $u.IsAbs }}
{{- /* Get remote image. */}}
{{- with resources.GetRemote $u.String }}
{{- with .Err }}
{{- warnf "%s" . }}
{{- else }}
{{- /* https://discourse.gohugo.io/t/36397 */}}
{{- $i := .Content | resources.FromString (path.Join "assets/images" .Name) }}
{{- $src = $i.RelPermalink }}
{{- end }}
{{- else }}
{{- warnf "Unable to retrieve remote image %q" $u.String }}
{{- end }}
{{- else }}
{{- with .Page.Resources.GetMatch $u.String }}
{{- $src = .RelPermalink }}
{{- else }}
{{- $ext := path.Ext $u.String }}
{{- $path := printf "%s.%s%s" (strings.TrimSuffix $ext $u.String) $.Page.Lang $ext }}
{{- with .Page.Resources.GetMatch $path }}
{{- $src = .RelPermalink }}
{{- else }}
{{- with resources.Get $u.String }}
{{- $src = .RelPermalink }}
{{- else }}
{{- warnf "Unable to retrieve local image %q" $u.String }}
{{- end }}
{{- end }}
{{- end }}
{{- end -}}
<img src="{{ $src }}" {{- with $title }} title="{{ . }}" {{- end }} {{- with $alt }} alt="{{ . }}" {{- end }}>
После этого при открытия статьи на основном языке будет абсолютный путь до картинки:
<img src="/hugo-obsidian/4.png" alt="Зашифрованные файлы">
И при открытии статьи на дополнительном языке будет такой же абсолютный путь без учета языка /en/
:
<img src="/hugo-obsidian/4.png" alt="Encrypted files">
Это значит что картинки будут открываться из статьи с основным языком.