Hugo 自带 Sitemap(站点地图)生成功能,会自动在根目录下生成一个 sitemap.xml 文件。不过默认生成的站点地图包含了一些可能不必要的内容,比如 archives 页面,各个 section 页面等,个人觉得这些条目重复了,这些其实全是 list,只是名称不一样,它们所包含的文章都是一样的,个人感觉没必要再让搜索引擎看一遍,所以我不希望它们出现在 sitemap.xml 里面。

另外,默认生成的站点地图是把所有条目按照时间倒序排列的,这就让 categories、tags 和 pages、posts 混到了一起,我个人不喜欢这样掺和到一块儿,我想要的是 pages 在前,然后是 posts,再接着才是 categories 和 tags,当然默认还是按时间倒序排列。

那么,怎样才能实现自定义 Sitemap 呢?其实 Hugo 自带的站点地图也是按照一个默认的 Sitemap template(模板)生成的,所以我们只需要新建一个自己的 Sitemap 模板,把默认的覆盖掉就可以了

我们只需要在站点的 themes/_default 目录下创建一个 sitemap.xml 文件,它就会覆盖 Hugo 自带的 Sitemap 模板。那么要实现前面说的要求这个自定义的模板要怎么写呢?只需罗列几个 range 再加个 if 判断就可以了,可行的代码如下:

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  {{- range where .Site.Pages "Type" "page" }}
  <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 -}}
  {{- range where .Site.RegularPages "Type" "post" }}
  <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 -}}
  {{- range .Data.Pages -}}
  {{- if eq .Kind "taxonomy" }}
  <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 -}}
  {{- end }}
</urlset>

从上面代码可以看出,我们分三段来生成,首先是 pages,接着是 posts,最后是 taxonomies(也就是 categories 和 tags),如此就可以生成我想要的格式了。

另外需要注意的是,Hugo 模板很容易引入大片的空行,在查看源代码时很不美观,所以上面的代码使用了很多 - 号,目的就是缩略掉多余的空行,从而使生成的 HTML 源代码(本例中是 XML 代码)更紧凑易读。