Hugoで人間が読みやすい多言語&カスタム投稿タイプ別サイトマップを作る方法

ghariza mahavira fZcSoRYtgBo unsplash scaled
Genxのアバター
Share This:

多言語対応かつカスタム投稿タイプを運用しているHugoサイトで、以下のような柔軟なサイトマップがほしいと思ったことはない?

  • 人間にもわかりやすい見た目(XSLで変換)
  • 言語ごとに分割
  • 投稿タイプ(postsやtechなど)ごとにも分割生成

ここでは、すぐ使える実践的な方法を紹介する。

1. XSLスタイルシートを追加してサイトマップを人間が読みやすく

通常、ブラウザでXMLサイトマップを見るとコードのままだが、XSLスタイルシートを使えば見やすくデザインできる。

staticディレクトリ内に以下のファイルを保存しよう。

static/sitemap.xsl(セクション用)

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9">
  <xsl:template match="/">
    <html>
      <head>
        <title>Sitemap</title>
        <style type="text/css">
          body { font-family: sans-serif; background: #fafafa; }
          ul { line-height: 2; list-style: disc inside; }
        </style>
      </head>
      <body>
        <h2>Sitemap Links</h2>
        <ul>
          <xsl:for-each select="sitemap:urlset/sitemap:url">
            <li>
              <a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a>
              <xsl:if test="sitemap:lastmod">
                <small> (Last modified: <xsl:value-of select="sitemap:lastmod"/>)</small>
              </xsl:if>
            </li>
          </xsl:for-each>
        </ul>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>
static/sitemapindex.xsl(インデックス用)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9">
  <xsl:template match="/">
    <html>
      <head>
        <title>Sitemap Index</title>
        <style type="text/css">
          body { font-family: sans-serif; background: #fafafa; }
          ul { line-height: 2; list-style: disc inside; }
        </style>
      </head>
      <body>
        <h2>Sitemap Index</h2>
        <ul>
          <xsl:for-each select="sitemap:sitemapindex/sitemap:sitemap">
            <li>
              <a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a>
              <xsl:if test="sitemap:lastmod">
                <small> (Last modified: <xsl:value-of select="sitemap:lastmod"/>)</small>
              </xsl:if>
            </li>
          </xsl:for-each>
        </ul>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

2. hugo.tomlの設定

hugo.toml

(多言語&カスタム出力形式)の該当部分を以下のように記述・修正する。

textdefaultContentLanguage = "en"

[languages]
  [languages.en]
    languageName = "English"
    weight = 1
  [languages.ja]
    languageName = "Japanese"
    weight = 2

[permalinks]
  posts = "/:slug/" # 英語(en)投稿はルート直下になる設定

[outputs]
home = ["HTML", "RSS", "SITEMAP"]
section = ["HTML", "RSS", "SITEMAP"]

[outputFormats]
  [outputFormats.SITEMAP]
    mediatype = "application/xml"
    baseName = "sitemap"
    isPlainText = true
    rel = "sitemap"

この設定で、Hugoは各セクション・各言語ごとに

sitemap.xml

を自動生成する。

3. ルート(トップ)用のサイトマップインデックス生成

layouts/_default/sitemap.xmlに下記を記述する。

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}
<?xml-stylesheet type="text/xsl" href="/sitemapindex.xsl"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  {{ range .Site.Sections }}
    <sitemap>
      <loc>{{ .Permalink }}sitemap.xml</loc>
      {{ with .Lastmod }}
        <lastmod>{{ .Format "2006-01-02T15:04:05Z07:00" }}</lastmod>
      {{ end }}
    </sitemap>
  {{ end }}
</sitemapindex>

ここでは、各セクション

(例:/posts/sitemap.xml、/tech/sitemap.xml)

へのリンク一覧を生成する。

4. セクションごとのサイトマップを生成

セクションごとに

sitemap.xml

をレイアウトとして追加する。

postsの場合

layouts/posts/sitemap.xmlを作成:

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}<?xml-stylesheet type="text/xsl" href="/sitemap.xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  {{ range (where .Site.Pages ".Section" "posts") }}
  <url>
    <loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }}
    <lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ end }}{{ with .Sitemap.ChangeFreq }}
    <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
    <priority>{{ .Sitemap.Priority }}</priority>{{ end }}
  </url>
  {{ end }}
</urlset>

カスタム投稿タイプ(例:tech)

layouts/tech/sitemap.xmlを作成:

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}
<?xml-stylesheet type="text/xsl" href="/sitemap.xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  {{ range (where .Site.Pages ".Section" "tech") }}
  <url>
    <loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }}
    <lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ end }}{{ with .Sitemap.ChangeFreq }}
    <changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
    <priority>{{ .Sitemap.Priority }}</priority>{{ end }}
  </url>
  {{ end }}
</urlset>

他にもカスタムセクションがある場合は同様に

layouts/[section]/sitemap.xml

を作成する。

5. Hugoによる自動多言語対応

Hugoは自動的に、それぞれの言語ごとのサイトマップを出力する。

例:http://localhost:1313/sitemap.xml, http://localhost:1313/ja/sitemap.xmlなど

特定言語だけ内容を変えたいなら、テンプレート内で.Langを使い分けられる。

6. 人間が見やすいサイトマップの確認

トップインデックス
http://localhost:1313/sitemap.xml
http://localhost:1313/ja/sitemap.xml

セクション別・言語別
http://localhost:1313/posts/sitemap.xml
http://localhost:1313/tech/sitemap.xml
http://localhost:1313/ja/posts/sitemap.xml
http://localhost:1313/ja/tech/sitemap.xml

ブラウザで開くと、XSLのおかげでとても見やすいサイトマップとして表示される。

追加カスタマイズ例

  • 各リンクにタイトルや説明を付加したい場合は、XSL内の <li> 要素をカスタム
  • XSLに言語切替リンクを追加するのもオススメ

ワンポイント

新しい投稿タイプや言語を追加した場合も、レイアウトファイル

(sitemap.xml

を追加するだけ。柔軟に拡張できる。

まとめ

この方法を使えば…

  • サイト運営者やSEO担当にも優しい「人間が読めるサイトマップ」
  • 投稿タイプ・言語ごとに整理された構造

をシンプルに実現できる。

関連記事

Genx

in

Comment

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

17 + 9 =

Webmention: Have you posted a response to this article? Let me know the URL: