hugoのSectionと多言語化

記事カテゴリー分類の機能を提供するのが Section です。

デフォルトでは、contents/ディレクトリの直下にあるディレクトリをセクションと見なします。
素朴な使い方では、記事をフォルダ分類し、ビルド後のサイトも対応するPathに並ぶため直感的な動作と言えます。

configに多言語設定を追加すると、contents/直下には言語別の原稿を持つ構成に変わります。そして、contents/en/のように各言語ディレクトリ直下からセクションが開始します。

セクションは、.Site.RegularPagesなどのパラメータに指定でき、記事リストを手続き的に取得したい場合にはrange .Site.RegularPages "Section" "<some-section>"のようにセクション名を指定します。

サブセクション

冒頭の公式ドキュメントの説明のとおり、contents/<some-section>/<sub-section>/のようにネストしたサブセクションを用いて記事を整理できます。ただし、フォルダを作成するだけでなく<sub-section>/_index.mdも存在する必要があります。

hugoのリストページはlist.htmlテンプレートに沿ってレンダリングしますが、サブセクションも一般的なlist.htmlでレンダリングでき、期待どおり<sub-section>/内の記事リストになります。

サブセクションはセクションではない

サブセクションのリストは自動的に抽出される一方、<some-section>/<sub-section>/内の記事のセクションはトップレベルの<some-section>になります。

よって、先ほどのrange .Site.RegularPages "Section" "<some-section>"で抽出した場合には、<sume-section>の子孫フォルダを含む記事をフラットに取り出す挙動になります。

サブセクションを直接操作するイディオムはありません。

サブセクションの記事セットを操作するには、.Site.GetPageでリストページを取得し、.Pagesコレクションを利用します。

  {{ with .Site.GetPage "page" "/<some-section>/<sub-section>/" }}
      {{ range .Pages }}
            <!-- Render each Page -->
      {{ end }}
  {{ end }}

多言語化

hugoの多言語化機能は、 Multilingual Mode に解説があります。

ただしマニュアルは複数のシナリオ向けのリファレンスになっていため、あらかじめ構成を決める必要があります。

  • 各国語サイトを個別サイトとして独立させる、または1つのサイトの各国語ページ構成にする、のいずれかを選択
    • 個別サイトのバリエーションとして、独立したサブディレクトリ構成も可能
  • 記事の原稿を言語別に分ける、または1つのディレクトリに混在させる、のいずれかを選択

各国語サイトの分割

言語設定はconfigのlanguagesセクションに記述します。
詳細に設定しない場合、hugoは1つのサイト内に多言語ページを持つ構成で生成する挙動となります。

各国語のサイトを個別に切り分ける構成にするには、 Configure Multilingual Multihost の設定が必要です。

[languages]
  [languages.en]
    baseURL = 'https://example.com'
  [languages.fr]
    baseURL = 'https://example.fr'

上の例ではbaseURLにドメインを指定していますが、同一ドメインのサブディレクトリを指定する構成も可能です。
この設定でhugoコマンドを実行すると、public/ディレクトリにen/とfr/の2つのサブディレクトリが生成されます。

サイト配置はホスティングの選択にもよる

1サイトに統合すると配信はシンプルです。
各国語サイトを作るとなると、その言語を用いる文化圏に近い場所からホストしたいケースが多くなるため、地理的に分散構成をとるのであれば複数サイト構成の必要性が高まります。

原稿のディレクトリ構成

原稿レイアウトのデフォルトは、各国語の原稿を単一ディレクトリに置く想定になっています。たとえば、sample.en.mdとsample.fr.mdのようにサブの拡張子に言語名を指定して、同じディレクトリに置きます。

言語別にディレクトリを分けたい場合、 Translation by content directory の追加設定が必要です。

[languages]
  [languages.en]
    contentDir = 'content/english'
  [languages.fr]
    contentDir = 'content/french'

デフォルトではcontent/ディレクトリ以下に原稿を置きますが、contentDirを分割した場合、各サブディレクトリに同じ構成で原稿を置きます。
ディレクトリ名・ファイル名が一致するものが、翻訳のあるコンテンツとして認識されます。

翻訳リンクの掲載

ここまでの設定により、似ているPathのファイル間でhugoが翻訳版を認識しますが、それらのリンク表示は Reference the Translated Content を参考にテンプレートに実装します。

{{ if .IsTranslated }}
<ul>
  {{ range .Translations }}
  <li>
    <a href="{{ .Permalink }}">{{ .Lang }}</a>
  </li>
  {{ end }}
</ul>
{{ end }}

あるページに対応する翻訳ページは、Pageオブジェクトの.Translationsに入ります。
特定の言語にしか存在しないページは、.Translationsが空になりリンク表示をスキップします。

言語別変数

hugoのconfigでは、title変数にサイト名称を設定できます。これらの変数は、各言語セクションにも定義でき言語別の設定が優先されます。
テンプレートから参照する変数も言語別に指定可能です。

多言語カタログ

言語設定と連動して、多言語メッセージカタログも利用できます。テンプレートで以下のようにi18n関数を呼ぶと、該当する言語のラベルに置換されます。

{{ i18n "some_catalog" }}

言語カタログデータは、テーマのトップディレクトリにi18nディレクトリを作成し、i18n/en.tomlのように言語別のファイルを置きます。

言語カタログは以下のような書式になっています。otheerは単数形・複数形などを識別するkeyになっており、区別しない場合はotherがデフォルト参照されるようです。

[some_catalog]
other = "Some meesage in english"

なお、カタログの言語選択は冒頭の言語コードをもとに選択されます。マニュアルでは"en-US"といった例で紹介されていますが、“en-US"という言語コードを定義した場合に参照されます。

i18nの詳細は Translation of Strings にマニュアルがあります。単純な置換だけでなく、ページ変数を利用したテンプレートも作成できます。

⁋ 2022/05/16↻ 2026/10/22