「記事の途中に複数の表(テーブル)を挿入したいけれど、Markdown記法だと複雑で後からの編集がしづらい…」
「メンバー紹介や商品の料金表など、頻繁に変わる可能性のあるデータを、直接記事の本文に埋め込みたくない…」

そんな時に非常に役立つのがHugoの data/ フォルダ です。
Hugoでは、コンテンツ本体(Markdown記事)と、構造化されたデータ(JSONやYAML等の情報)を完全に分離して管理できる機能が備わっています。

今回はその便利さを実感するために、「テンプレート変数の早見表」 を例にして、データの分離記述とショートコードを利用した画面への呼び出しを実践してみましょう!

1. 📂 data/ フォルダとは

「記事にするほど長文ではないけれど、構造化して管理したい情報」を置く場所です。
ここに置いたデータは、サイト内のどこからでも(どの記事、どのテンプレートからでも)呼び出すことができます。

ここに置くのに向いているもの

  • メンバー紹介リスト
  • 商品のスペック一覧
  • サイト内の独自設定値
  • よく使うリンク集
  • 今回作る「変数の一覧表」

ここにおいたファイルは、Hugoのテンプレートから site.Data.ファイル名 という形で簡単に使えます。


2. hugo.tomldata/ の使い分け

「ちょっと待って、サイト全体の設定なら hugo.toml に書けばいいんじゃないの?」
その通りです!迷った時は以下のように使い分けましょう。

🅰️ hugo.toml ([params]) に書くべきもの

「値が1つだけのもの」「サイト全体で使う単純な設定」 です。

[params]
  copyright = "My Blog Inc."  # コピーライト表記
  address = "東京都渋谷区..."   # 住所
  phone = "03-1234-5678"      # 電話番号
  postLimit = 10              # 記事の表示件数

テンプレートからの呼び出し: {{ site.Params.address }}

🅱️ data/ フォルダに置くべきもの

「リスト(配列)になるもの」「情報量が多いもの」 です。
hugo.toml に大量のリストを書くと、設定ファイルが読みづらくなってしまいます。

  • hugo.toml: メニュー、社員リスト、商品データなど(長すぎる!)
  • data/: 上記のような構造化データ

3. 実践:変数リストを作る

作業フォルダのルートにある data フォルダの中に、hugo_vars.json というファイルを作ってください。
(もし data フォルダがなければ作ってください)

[
  {
    "name": ".Title",
    "description": "記事のタイトル。Front Matterの title フィールドから取得されます。",
    "context": "Page"
  },
  {
    "name": ".Date",
    "description": "記事の日付。Front Matterの date フィールドから取得されます。",
    "context": "Page"
  },
  {
    "name": ".Site.Title",
    "description": "サイト全体のタイトル。設定ファイルの title から取得されます。",
    "context": "Site"
  }
]

(実際にはもっとたくさんのデータを入れています!)

4. ショートコードを作る

次に、このデータを記事の中に表示するための機能 「ショートコード」 を作ります。
ショートコードとは、Markdownの中に {{< ... >}} と書くだけで、複雑なHTMLを埋め込める便利機能です。
(作り方の詳細は ショートコードの作り方 で解説しています)

themes/my-tutorial-theme/layouts/shortcodes/varlist.html を作成し、以下のように記述します。

<table>
  <thead>
    <tr>
      <th>変数名</th>
      <th>コンテキスト</th>
      <th>説明</th>
    </tr>
  </thead>
  <tbody>
    <!-- site.Data.hugo_vars の中身をループ処理 -->
    {{ range site.Data.hugo_vars }}
    <tr>
      <td><code>{{ .name }}</code></td>
      <td>{{ .context }}</td>
      <td>{{ .description }}</td>
    </tr>
    {{ end }}
  </tbody>
</table>

5. 完成!

では、実際に表示させてみましょう。
この記事のMarkdownファイルに、たった一行、こう書くだけです。

{{< varlist >}}

すると……?

👇 実際の表示結果がこちら! 👇

変数名コンテキスト説明
.TitlePage記事のタイトル。Front Matterの title フィールドから取得されます。
.ContentPage記事の本文(HTML変換後)。
.DatePage記事の日付。Front Matterの date フィールドから取得されます。
.PermalinkPageそのページの完全なURL(例: https://example.com/posts/hello/)。
.RelPermalinkPageそのページの相対URL(例: /posts/hello/)。内部リンクに便利です。
.Site.TitleSiteサイト全体のタイトル。設定ファイルの title から取得されます。
.Site.BaseURLSiteサイトのベースURL。設定ファイルで定義されています。
.Site.PagesSiteサイト内の全てのページ(セクション含む)のコレクション。
.Site.RegularPagesSiteサイト内の通常ページ(記事など)だけのコレクション。
変数名コンテキスト説明
.TitlePage記事のタイトル。Front Matterの title フィールドから取得されます。
.ContentPage記事の本文(HTML変換後)。
.DatePage記事の日付。Front Matterの date フィールドから取得されます。
.PermalinkPageそのページの完全なURL(例: https://example.com/posts/hello/)。
.RelPermalinkPageそのページの相対URL(例: /posts/hello/)。内部リンクに便利です。
.Site.TitleSiteサイト全体のタイトル。設定ファイルの title から取得されます。
.Site.BaseURLSiteサイトのベースURL。設定ファイルで定義されています。
.Site.PagesSiteサイト内の全てのページ(セクション含む)のコレクション。
.Site.RegularPagesSiteサイト内の通常ページ(記事など)だけのコレクション。

データと表示テンプレートを分離してメンテナンス性を高めよう

見事、JSONファイルの内容がHTMLのテーブルとして記事に自動出力されましたね!
これなら、変数の説明文や項目を後から追加・修正したくなった時も、data/hugo_vars.json のテキストデータを書き換えるだけで済み、記事のMarkdownファイル本体をいちいち探して修正する必要はありません。

「商品リスト」や「メンバー紹介」といった管理項目が多い変動データはなるべくJSONなどに分離する。これが、長期間スマートにサイトを維持・管理するための賢いコツです!💡