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 <kolappannathan@users.noreply.github.com>
Co-authored-by: felicianotech <FelicianoTech@gmail.com>
This commit is contained in:
Joe Mooring 2024-04-01 15:30:03 -07:00 committed by Bjørn Erik Pedersen
parent 2f7df4b926
commit 6738a3e79d
6 changed files with 62 additions and 8 deletions

View file

@ -215,6 +215,8 @@ type SitemapConfig struct {
Priority float64 Priority float64
// The sitemap filename. // The sitemap filename.
Filename string Filename string
// Whether to disable page inclusion.
Disable bool
} }
func DecodeSitemap(prototype SitemapConfig, input map[string]any) (SitemapConfig, error) { func DecodeSitemap(prototype SitemapConfig, input map[string]any) (SitemapConfig, error) {

View file

@ -1649,6 +1649,7 @@ config:
disableInlineCSS: false disableInlineCSS: false
sitemap: sitemap:
changeFreq: "" changeFreq: ""
disable: false
filename: sitemap.xml filename: sitemap.xml
priority: -1 priority: -1
social: null social: null
@ -2797,8 +2798,8 @@ tpl:
{{ $m.Set "Hugo" "Rocks!" }} {{ $m.Set "Hugo" "Rocks!" }}
{{ $m.Values | debug.Dump | safeHTML }} {{ $m.Values | debug.Dump | safeHTML }}
- |- - |-
map[string]interface {}{ {
"Hugo": "Rocks!", "Hugo": "Rocks!"
} }
TestDeprecationErr: TestDeprecationErr:
Aliases: null Aliases: null

View file

@ -490,11 +490,10 @@ name = "menu-theme"
got := b.Configs.Base got := b.Configs.Base
if mergeStrategy == "none" { 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") b.AssertFileContent("public/sitemap.xml", "schemas/sitemap")
} else { } 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", "<changefreq>monthly</changefreq>") b.AssertFileContent("public/sitemap.xml", "<changefreq>monthly</changefreq>")
} }
}) })

View file

@ -108,11 +108,12 @@ outputs: [ "html", "amp" ]
func TestParseSitemap(t *testing.T) { func TestParseSitemap(t *testing.T) {
t.Parallel() 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{ input := map[string]any{
"changefreq": "3", "changefreq": "3",
"priority": 3.0, "disable": true,
"filename": "doo.xml", "filename": "doo.xml",
"priority": 3.0,
"unknown": "ignore", "unknown": "ignore",
} }
result, err := config.DecodeSitemap(config.SitemapConfig{}, input) result, err := config.DecodeSitemap(config.SitemapConfig{}, input)

View file

@ -1,7 +1,7 @@
{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }} {{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xhtml="http://www.w3.org/1999/xhtml"> xmlns:xhtml="http://www.w3.org/1999/xhtml">
{{ range .Data.Pages }} {{ range where .Pages "Sitemap.Disable" "ne" true }}
{{- if .Permalink -}} {{- if .Permalink -}}
<url> <url>
<loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }} <loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }}

View file

@ -254,3 +254,54 @@ disable = false
`s.src = '//' + "foo" + '.disqus.com/embed.js';`, `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",
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">\n \n</urlset>\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",
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">\n <url>\n <loc>/p1/</loc>\n </url><url>\n <loc>/p2/</loc>\n </url>\n</urlset>\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",
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">\n <url>\n <loc>/p1/</loc>\n </url>\n</urlset>\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",
"<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">\n <url>\n <loc>/p2/</loc>\n </url>\n</urlset>\n",
)
}