多言語対応かつカスタム投稿タイプを運用している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担当にも優しい「人間が読めるサイトマップ」
- 投稿タイプ・言語ごとに整理された構造
をシンプルに実現できる。
コメントを残す