From 6738a3e79dd545603d9851832bc3140fd184bfef Mon Sep 17 00:00:00 2001 From: Joe Mooring Date: Mon, 1 Apr 2024 15:30:03 -0700 Subject: [PATCH] tpl/tplimpl: Optionally exclude content from sitemap Define global inclusion/exclusion in site configuration, and override via front matter. For example, to exclude a page from the sitemap: [sitemap] disable = true # default is false Closes #653 Closes #12282 Co-authored-by: kolappannathan Co-authored-by: felicianotech --- config/commonConfig.go | 2 + docs/data/docs.yaml | 5 +- hugolib/config_test.go | 5 +- hugolib/sitemap_test.go | 5 +- .../embedded/templates/_default/sitemap.xml | 2 +- tpl/tplimpl/tplimpl_integration_test.go | 51 +++++++++++++++++++ 6 files changed, 62 insertions(+), 8 deletions(-) diff --git a/config/commonConfig.go b/config/commonConfig.go index 6ca061093..6ae97c2a1 100644 --- a/config/commonConfig.go +++ b/config/commonConfig.go @@ -215,6 +215,8 @@ type SitemapConfig struct { Priority float64 // The sitemap filename. Filename string + // Whether to disable page inclusion. + Disable bool } func DecodeSitemap(prototype SitemapConfig, input map[string]any) (SitemapConfig, error) { diff --git a/docs/data/docs.yaml b/docs/data/docs.yaml index f9b5731f2..b522ffbef 100644 --- a/docs/data/docs.yaml +++ b/docs/data/docs.yaml @@ -1649,6 +1649,7 @@ config: disableInlineCSS: false sitemap: changeFreq: "" + disable: false filename: sitemap.xml priority: -1 social: null @@ -2797,8 +2798,8 @@ tpl: {{ $m.Set "Hugo" "Rocks!" }} {{ $m.Values | debug.Dump | safeHTML }} - |- - map[string]interface {}{ - "Hugo": "Rocks!", + { + "Hugo": "Rocks!" } TestDeprecationErr: Aliases: null diff --git a/hugolib/config_test.go b/hugolib/config_test.go index 22beea655..8acf8b36e 100644 --- a/hugolib/config_test.go +++ b/hugolib/config_test.go @@ -490,11 +490,10 @@ name = "menu-theme" got := b.Configs.Base if mergeStrategy == "none" { - b.Assert(got.Sitemap, qt.DeepEquals, config.SitemapConfig{ChangeFreq: "", Priority: -1, Filename: "sitemap.xml"}) - + b.Assert(got.Sitemap, qt.DeepEquals, config.SitemapConfig{ChangeFreq: "", Disable: false, Priority: -1, Filename: "sitemap.xml"}) b.AssertFileContent("public/sitemap.xml", "schemas/sitemap") } else { - b.Assert(got.Sitemap, qt.DeepEquals, config.SitemapConfig{ChangeFreq: "monthly", Priority: -1, Filename: "sitemap.xml"}) + b.Assert(got.Sitemap, qt.DeepEquals, config.SitemapConfig{ChangeFreq: "monthly", Disable: false, Priority: -1, Filename: "sitemap.xml"}) b.AssertFileContent("public/sitemap.xml", "monthly") } }) diff --git a/hugolib/sitemap_test.go b/hugolib/sitemap_test.go index a5a94c67e..1c2642468 100644 --- a/hugolib/sitemap_test.go +++ b/hugolib/sitemap_test.go @@ -108,11 +108,12 @@ outputs: [ "html", "amp" ] func TestParseSitemap(t *testing.T) { t.Parallel() - expected := config.SitemapConfig{Priority: 3.0, Filename: "doo.xml", ChangeFreq: "3"} + expected := config.SitemapConfig{ChangeFreq: "3", Disable: true, Filename: "doo.xml", Priority: 3.0} input := map[string]any{ "changefreq": "3", - "priority": 3.0, + "disable": true, "filename": "doo.xml", + "priority": 3.0, "unknown": "ignore", } result, err := config.DecodeSitemap(config.SitemapConfig{}, input) diff --git a/tpl/tplimpl/embedded/templates/_default/sitemap.xml b/tpl/tplimpl/embedded/templates/_default/sitemap.xml index b1e4b2d2d..de1f467d1 100644 --- a/tpl/tplimpl/embedded/templates/_default/sitemap.xml +++ b/tpl/tplimpl/embedded/templates/_default/sitemap.xml @@ -1,7 +1,7 @@ {{ printf "" | safeHTML }} - {{ range .Data.Pages }} + {{ range where .Pages "Sitemap.Disable" "ne" true }} {{- if .Permalink -}} {{ .Permalink }}{{ if not .Lastmod.IsZero }} diff --git a/tpl/tplimpl/tplimpl_integration_test.go b/tpl/tplimpl/tplimpl_integration_test.go index abda3af29..28d442e0d 100644 --- a/tpl/tplimpl/tplimpl_integration_test.go +++ b/tpl/tplimpl/tplimpl_integration_test.go @@ -254,3 +254,54 @@ disable = false `s.src = '//' + "foo" + '.disqus.com/embed.js';`, ) } + +func TestSitemap(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ['home','rss','section','taxonomy','term'] +[sitemap] +disable = true +-- content/p1.md -- +--- +title: p1 +sitemap: + p1_disable: foo +--- +-- content/p2.md -- +--- +title: p2 + +--- +-- layouts/_default/single.html -- +{{ .Title }} +` + + // Test A: Exclude all pages via site config. + b := hugolib.Test(t, files) + b.AssertFileContentExact("public/sitemap.xml", + "\n\n \n\n", + ) + + // Test B: Include all pages via site config. + files_b := strings.ReplaceAll(files, "disable = true", "disable = false") + b = hugolib.Test(t, files_b) + b.AssertFileContentExact("public/sitemap.xml", + "\n\n \n /p1/\n \n /p2/\n \n\n", + ) + + // Test C: Exclude all pages via site config, but include p1 via front matter. + files_c := strings.ReplaceAll(files, "p1_disable: foo", "disable: false") + b = hugolib.Test(t, files_c) + b.AssertFileContentExact("public/sitemap.xml", + "\n\n \n /p1/\n \n\n", + ) + + // Test D: Include all pages via site config, but exclude p1 via front matter. + files_d := strings.ReplaceAll(files_b, "p1_disable: foo", "disable: true") + b = hugolib.Test(t, files_d) + b.AssertFileContentExact("public/sitemap.xml", + "\n\n \n /p2/\n \n\n", + ) +}