概要
新しいブログのテストがてら記事を書いていたら画像の挿入でハマった話. 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に詳しくなってきた気がする.