May 15, 2021

Hugoでpermalinksを設定しているときの画像URLの不具合と修正方法

新しいブログのテストがてら記事を書いていたら画像の挿入でハマった話

概要

新しいブログのテストがてら記事を書いていたら画像の挿入でハマった話. permalinksが曲者だったけどHugoのテンプレート追加して解決した.

問題

このブログでは下記のようなpermalinkをconfig.tomlで設定している(URLをはてなブログっぽくしてる).

[permalinks]
post = "/:year/:month/:day/:15:04:05"

フォルダの構成は以下のようになってて,記事のMarkdownファイルと同名のフォルダ内に画像を置くことで記事に画像を貼っている.

.
│  config.toml
│
├─content
    │  about.md
    │
    └─post
        │  plot_categorical.md
        │
        └─plot_categorical
                Figure_1.png
                Figure_2.png
                Figure_3.png
                Figure_4.png

Markdownで画像を貼るには下記のコマンドを使うが,このとき,指定したファイルをそのページの相対パスから探そうとするため,画像が見つからないという問題が発生する(この場合だと/post/2021/05/13/001208/Figure_1.pngを探そうとするが,正しくは/post/plot_categorical/Figure_1.png).

![img](Figure_1.png)

解決方法

手動で解決する方法

素直にルートからのパスを書けばいい:

![img](/post/plot_categorical/Figure_1.png)

でも記事ごとにパスが変わるのでちょっと気持ち悪い感じがする.もし記事のファイル名を変えることがあったら,記事中の全ての画像のパスを直す必要がでてくる.できれば![img](Figure_1.png)の書き方のままで画像が参照されてほしい.

Markdown Render Hooksによる解決方法

HugoにはMarkdown Render Hooksという機能があり,MarkdownをHTMLに変換する際,間にHugoのテンプレートを割り込ませることができる.詳しくは下記ページを参考にされたい.

https://kamoqq.info/post/hugo-render-hook-templates/

これを利用し,記事中の<img>タグが生成される際,画像のパスを修正することで問題を解決した.

今回は下記の内容のファイルlayouts\_default\_markup\render-image.htmlを作ることで対処した.

{{ if eq .Page.Type "post" }}
{{ $file_dir := print "/" ( substr .Page.File.Dir 0 -1 ) "/" ( .Page.File.BaseFileName ) }}
<img src="{{ print $file_dir "/" .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}"{{ end }} />
{{ else }}
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}"{{ end }} />
{{ end }}

簡単に解説すると,最初のif文は処理中のファイルがブログ記事(post)かどうかを判定している.将来的にブログ記事以外のページで変な挙動をされると困るので分岐させている.{{ else }}側のタグはデフォルトの出力と同じ.

{{ if eq .Page.Type "post" }}

次の文で記事があるフォルダ名(post)と拡張子を除いた記事名を取得してURLになるようにくっつける:

{{ $file_dir := print "/" ( substr .Page.File.Dir 0 -1 ) "/" ( .Page.File.BaseFileName ) }}

最後に,フォルダ名と画像ファイル名をくっつけることでimgタグのsrcを作っている.

<img src="{{ print $file_dir "/" .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title}} title="{{ . }}"{{ end }} />

おわり.色々調べてHugoに詳しくなってきた気がする.

© eqs 2021