mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
output: Fix permalink in sitemap etc. when multiple permalinkable output formats
In Hugo 0.55.0 we made AMP `permalinkable`. We also render the output formats in their natural sort order, meaning `AMP` will be rendered before `HTML`. References in the sitemap would then point to the AMP version, and this is normally not what you'd want. This commit fixes that by making `HTML` by default sort before the others. If this is not you want, you can set `weight` on the output format configuration. Fixes #5910
This commit is contained in:
parent
bcbed4ebda
commit
6b76841b05
4 changed files with 65 additions and 4 deletions
|
@ -35,7 +35,7 @@ type siteRenderContext struct {
|
||||||
sitesOutIdx int
|
sitesOutIdx int
|
||||||
|
|
||||||
// Zero based index of the output formats configured within a Site.
|
// Zero based index of the output formats configured within a Site.
|
||||||
// Note that these outputs are sorted, so CSS will come before HTML.
|
// Note that these outputs are sorted.
|
||||||
outIdx int
|
outIdx int
|
||||||
|
|
||||||
multihost bool
|
multihost bool
|
||||||
|
|
|
@ -100,3 +100,22 @@ func TestParseSitemap(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/gohugoio/hugo/issues/5910
|
||||||
|
func TestSitemapOutputFormats(t *testing.T) {
|
||||||
|
|
||||||
|
b := newTestSitesBuilder(t).WithSimpleConfigFile()
|
||||||
|
|
||||||
|
b.WithContent("blog/html-amp.md", `
|
||||||
|
---
|
||||||
|
Title: AMP and HTML
|
||||||
|
outputs: [ "html", "amp" ]
|
||||||
|
---
|
||||||
|
|
||||||
|
`)
|
||||||
|
|
||||||
|
b.Build(BuildCfg{})
|
||||||
|
|
||||||
|
// Should link to the HTML version.
|
||||||
|
b.AssertFileContent("public/sitemap.xml", " <loc>http://example.com/blog/html-amp/</loc>")
|
||||||
|
}
|
||||||
|
|
|
@ -78,6 +78,9 @@ type Format struct {
|
||||||
// example. AMP would, however, be a good example of an output format where this
|
// example. AMP would, however, be a good example of an output format where this
|
||||||
// behaviour is wanted.
|
// behaviour is wanted.
|
||||||
Permalinkable bool `json:"permalinkable"`
|
Permalinkable bool `json:"permalinkable"`
|
||||||
|
|
||||||
|
// Setting this to a non-zero value will be used as the first sort criteria.
|
||||||
|
Weight int `json:"weight"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// An ordered list of built-in output formats.
|
// An ordered list of built-in output formats.
|
||||||
|
@ -125,6 +128,10 @@ var (
|
||||||
Rel: "canonical",
|
Rel: "canonical",
|
||||||
IsHTML: true,
|
IsHTML: true,
|
||||||
Permalinkable: true,
|
Permalinkable: true,
|
||||||
|
|
||||||
|
// Weight will be used as first sort criteria. HTML will, by default,
|
||||||
|
// be rendered first, but set it to 10 so it's easy to put one above it.
|
||||||
|
Weight: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONFormat = Format{
|
JSONFormat = Format{
|
||||||
|
@ -180,9 +187,21 @@ func init() {
|
||||||
// Formats is a slice of Format.
|
// Formats is a slice of Format.
|
||||||
type Formats []Format
|
type Formats []Format
|
||||||
|
|
||||||
func (formats Formats) Len() int { return len(formats) }
|
func (formats Formats) Len() int { return len(formats) }
|
||||||
func (formats Formats) Swap(i, j int) { formats[i], formats[j] = formats[j], formats[i] }
|
func (formats Formats) Swap(i, j int) { formats[i], formats[j] = formats[j], formats[i] }
|
||||||
func (formats Formats) Less(i, j int) bool { return formats[i].Name < formats[j].Name }
|
func (formats Formats) Less(i, j int) bool {
|
||||||
|
fi, fj := formats[i], formats[j]
|
||||||
|
if fi.Weight == fj.Weight {
|
||||||
|
return fi.Name < fj.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
if fj.Weight == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return fi.Weight > 0 && fi.Weight < fj.Weight
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// GetBySuffix gets a output format given as suffix, e.g. "html".
|
// GetBySuffix gets a output format given as suffix, e.g. "html".
|
||||||
// It will return false if no format could be found, or if the suffix given
|
// It will return false if no format could be found, or if the suffix given
|
||||||
|
|
|
@ -15,6 +15,7 @@ package output
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/gohugoio/hugo/media"
|
"github.com/gohugoio/hugo/media"
|
||||||
|
@ -225,3 +226,25 @@ func TestDecodeFormats(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSort(t *testing.T) {
|
||||||
|
assert := require.New(t)
|
||||||
|
assert.Equal("HTML", DefaultFormats[0].Name)
|
||||||
|
assert.Equal("AMP", DefaultFormats[1].Name)
|
||||||
|
|
||||||
|
json := JSONFormat
|
||||||
|
json.Weight = 1
|
||||||
|
|
||||||
|
formats := Formats{
|
||||||
|
AMPFormat,
|
||||||
|
HTMLFormat,
|
||||||
|
json,
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(formats)
|
||||||
|
|
||||||
|
assert.Equal("JSON", formats[0].Name)
|
||||||
|
assert.Equal("HTML", formats[1].Name)
|
||||||
|
assert.Equal("AMP", formats[2].Name)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue