Hugoを使っていると、「Markdownで書いたテーブルをもっと綺麗に見せたい」「画像には必ず特定のクラスを付けたい」といった要望が出てくることがあります。

通常、Markdownは標準的なHTMLタグ(<table><img><a> など)に自動変換されますが、Hugoにはその**「変換時の出力ルール」を自分好みに上書きできる強力な機能**があります。
それが 「Markdown Render Hooks(マークダウン・レンダー・フック)」 です。

本記事では、この機能の基本的な仕組みと、実践的な活用例(スマホ対応のテーブル等)について解説します。


1. Markdown Render Hooks とは?

Markdown Render Hooks は、HugoがMarkdownをHTMLに変換するプロセスに割り込んで(フックして)、独自のテンプレート処理を適用できる機能です。

対応している要素としては、主に以下の4つがあります:

  • 画像 (![]()) 👉 render-image.html
  • リンク ([]()) 👉 render-link.html
  • 見出し (#, ##) 👉 render-heading.html
  • テーブル 👇 render-table.html

これらをカスタマイズすることで、ただのMarkdownを高度なコンポーネントに変身させることができます。


2. フックファイルの置き場所

カスタマイズ用のテンプレート(フックファイル)は、以下のディレクトリに配置します。
(Hugo v0.146.0 以降のモダンなテンプレートシステムに準拠しています。)

基本の配置場所:
layouts/_markup/ の直下に配置します。

my-tutorial-theme/
└── layouts/
    └── _markup/
        ├── render-image.html   # 画像用
        ├── render-link.html    # リンク用
        └── render-table.html   # テーブル用

【参考】古いHugoバージョンの場合:
以前は layouts/_default/_markup/ という階層を使用することが推奨されていましたが、Hugo v0.146.0 にて _default フォルダは廃止・統合されたため、現在新しくテーマを作る場合は layouts/_markup/ を使用してください。
参考記事: layoutsフォルダの役割と仕組み


3. 実践:スマホで横スクロールできるテーブルを作る

当サイト(チュートリアル)でも実装されている、 幅の広いテーブルをスマホで見た時に横スクロールさせる カスタマイズを例に解説します。

通常、Markdownで書いたテーブルは単純な <table> レンダリングとなるため、スマホのような狭い画面ではレイアウトが崩れたり、画面外にはみ出したりしてしまいます。

これを解決するために、テーブル全体を <div class="table-wrapper"> で囲むようにルールを変更します。

Step 1: render-table.html の作成

以下のパスにファイルを作成します。
themes/my-tutorial-theme/layouts/_markup/render-table.html(またはプロジェクトルートの layouts/_markup/render-table.html

<div class="table-wrapper">
  <table>
    <thead>
      {{- range .THead }}
        <tr>
          {{- range . }}
            <th{{ with .Alignment }} style="text-align: {{ . }}"{{ end }}>
              {{- .Text -}}
            </th>
          {{- end }}
        </tr>
      {{- end }}
    </thead>
    <tbody>
      {{- range .TBody }}
        <tr>
          {{- range . }}
            <td{{ with .Alignment }} style="text-align: {{ . }}"{{ end }}>
              {{- .Text -}}
            </td>
          {{- end }}
        </tr>
      {{- end }}
    </tbody>
  </table>
</div>

解説:

  • テンプレート変数 .THead.TBody には、Hugoが解析したMarkdownテーブルの中身(行やセル、配置位置など)が格納されています。
  • それらを range でループさせながら、全体の周りを <div class="table-wrapper"> で囲っています。

Step 2: CSSにスタイルを追加

独自のラッパー(div)が追加されたので、あとはそれにCSSをあてるだけです。
static/css/style.css などのスタイルシートに以下を追記します。

/* テーブルのスマホ横スクロール対応 */
.table-wrapper {
    width: 100%;
    overflow-x: auto; /* はみ出した場合にスクロールバーを表示 */
    -webkit-overflow-scrolling: touch; /* iOSでのスクロールを滑らかに */
    margin-bottom: 1.5em; /* 下部の余白 */
}

/* ついでにテーブル自体のベーススタイルも指定 */
table {
    width: 100%;
    border-collapse: collapse;
    min-width: 500px; /* ここがポイント!最低幅を指定することでスクロールを誘発します */
}

th, td {
    padding: 10px;
    border: 1px solid var(--border-color);
}

th {
    background-color: var(--header-bg);
    color: var(--header-text);
}

これで、画面幅が500pxを下回ると、テーブル自体は縮まずに横方向へスクロールできるようになります!


4. 他の活用アイデア

Markdown Render Hooksには、他にも以下のような便利な使い道があります。

  • 画像の最適化 (render-image.html)
    • <picture> タグを出力したり、画像を自動でリサイズして srcset を付与したりできます。 画像処理(Hugo Pipes) と組み合わせると強力です。
  • 外部リンクの自動「別タブ」化 (render-link.html)
    • URLが外部サイト(http から始まる)の場合のみ、自動的に target="_blank" rel="noopener noreferrer" を付与する、といった処理が書けます。
  • 見出しへのアンカーリンク付与 (render-heading.html)
    • 目次から飛べるように、すべての見出しタグ(<h2> など)の横に自動で「#(アンカーリンク)」を付けることができます。

まとめ

Markdown Render Hooks を活用すると、「記事を書くときはシンプルなMarkdownで快適に、表示するときはリッチなHTMLで美しく」 という、理想的なシステムを構築できます。

一度設定を作ってしまえば全ての記事に自動で適用されるため、運用の手間が大幅に省けます。「このタグを出力する時、もうひと手間加えられたらな…」と思ったら、ぜひこのフック機能を思い出してください!