Hugo Markdown Render Hooks 入門

Hugo v0.62.0 クリスマスエディションが今年もリリースされました。

- [Hugo v0.62.0 release notes](https://gohugo.io/news/0.62.0-relnotes/)

今回の目玉機能 Markdown Render Hooks の使い方を解説します。

Hooks は Markdown parser に Goldmark を利用している時に利用可能で、最新の Hugo はデフォルト Markdown parser が Goldmark です。

- [Markdown Render Hooks - Configure Markup | Hugo](https://gohugo.io/getting-started/configuration-markup/#markdown-render-hooks)

Markdown Render Hooks はリンクや画像に対してある属性を付けたい、など共通の処理を施したい時に重宝します。ショートコードを作らなければならない場面がぐっと減るでしょう。ショートコードではなく、普通のマークダウンを維持できるので、エディターや Headless CMS のプレビュー機能との親和性が高まったと思います。



## Markdown Render Hooks リンク編

導入方法は以下のような `layouts/_default/_markup/render-link.html` を作成するだけです。

```html
<a
  href="{{ .Destination | safeURL }}"
  {{ with .Title }} title="{{ . }}"{{ end }}
  {{ if strings.HasPrefix .Destination "http" }}target="_blank" rel="noopener"{{ end }}>
  {{ .Text }}
</a>
```

そしてコンテンツに Markdown 記法で以下のようなリンクを書くと、

```md
[Hugo](https://gohugo.io/ "Hugo homepage")
```

次のような HTML が生成されます。

```html
<a href="https://gohugo.io/" title="Hugo homepage" target="_blank" rel="noopener">
  Hugo
</a>
```

これにより `http` で始まる外部リンクに対して `target="_blank" rel="noopener"` を 自動的に付与できるようになりました。内部リンクは `[My post](/posts/path/to/article.md)` のように書くと思うので `target="_blank"` が付与されることはありません。

参考: [Handle external links with Render Hook Templates - tips & tricks - Hugo](https://discourse.gohugo.io/t/handle-external-links-with-render-hook-templates/22452/8)



## Markdown Render Hooks 画像編

画像にも Markdown Render Hook を設定できます。例えば以下のようにリサイズ処理を仕込むことが可能です。ファイルは `layouts/_default/_markup/render-image.html` です。

```html
{{ $image := .Page.Resources.GetMatch (printf "%s" (.Destination | safeURL)) }}
{{ $small := $image.Resize "480x jpg" }}
{{ $medium := $image.Resize "768x jpg" }}
{{ $large := $image.Resize "1024x jpg" }}
{{ $alt := .PlainText | safeHTML }}

<picture>
  <source media="(max-width: 480px)" srcset="{{ $small.RelPermalink }} 480w">
  <source media="(max-width: 768px)" srcset="{{ $medium.RelPermalink }} 768w">
  <source media="(max-width: 1024px)" srcset="{{ $large.RelPermalink }} 1024w">
  <img src="{{ $image.RelPermalink }}" alt="{{ $alt }}" decoding="async" loading="lazy">
</picture>
```

マークダウンは普通の記法を書くことができます。

```md
![Gopher image](path/to/gopher_image.jpg)
```

以下は実際に `hugo server` してページソースをブラウザで見たものです。

```html
<picture>
  <source media="(max-width: 480px)" srcset="http://localhost:1313/posts/github-pages-and-github-actions/eyecatch_hu3797a08418e1e841687b41b638a04d4c_44015_480x0_resize_q75_box.jpg 480w">
  <source media="(max-width: 768px)" srcset="http://localhost:1313/posts/github-pages-and-github-actions/eyecatch_hu3797a08418e1e841687b41b638a04d4c_44015_768x0_resize_q75_box.jpg 768w">
  <source media="(max-width: 1024px)" srcset="http://localhost:1313/posts/github-pages-and-github-actions/eyecatch_hu3797a08418e1e841687b41b638a04d4c_44015_1024x0_resize_q75_box.jpg 1024w">
  <img src="http://localhost:1313/posts/github-pages-and-github-actions/eyecatch.jpg" alt="GitHub Actions for GitHub Pages" decoding="async" loading="lazy">
</picture>
```

参考:

- [Image Processing | Hugo](https://gohugo.io/content-management/image-processing/)
- [Simple image render hook template for responsive images - tips & tricks - Hugo](https://discourse.gohugo.io/t/simple-image-render-hook-template-for-responsive-images/22464)



## 従来のアプローチ

[replaceRE](https://gohugo.io/functions/replaceRE/) とかでゴリゴリやったり、Shortcode を作ったりしていました。

Markdown Render Hooks を使えば Markdown 記法でリンクや画像を設置できるため、エディターや Netlify CMS などでちゃんとプレビューできるようになります。積極的に使っていきたいですね。