mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-24 07:18:54 +00:00
hugolib: Use the output format's suffix for alias paths
Alias generation hardcoded "index.html" and only recognized a ".html" suffix, so an alias with an explicit ".htm" extension (or any other suffix configured for the html media type) was written to the wrong path. For example "d.htm" produced the directory "d.htm/index.html" instead of the file "d.htm". Build the alias file name from the output format's BaseName and the media type's first suffix, and detect an explicit file by matching the alias extension against the configured suffixes. The same check now drives the uglyURLs case in Aliases. Fixes #15066
This commit is contained in:
committed by
Bjørn Erik Pedersen
parent
65c82178b7
commit
feb3d494b9
+16
-6
@@ -96,7 +96,7 @@ func (s *Site) writeDestAlias(path, permalink string, outputFormat output.Format
|
||||
func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, outputFormat output.Format, p page.Page) (err error) {
|
||||
handler := newAliasHandler(s.GetTemplateStore(), s.Log, allowRoot)
|
||||
|
||||
targetPath, err := handler.targetPathAlias(path)
|
||||
targetPath, err := handler.targetPathAlias(path, outputFormat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func (s *Site) publishDestAlias(allowRoot bool, path, permalink string, outputFo
|
||||
return s.publisher.Publish(pd)
|
||||
}
|
||||
|
||||
func (a aliasHandler) targetPathAlias(src string) (string, error) {
|
||||
func (a aliasHandler) targetPathAlias(src string, of output.Format) (string, error) {
|
||||
originalAlias := src
|
||||
if len(src) <= 0 {
|
||||
return "", fmt.Errorf("alias \"\" is an empty string")
|
||||
@@ -176,13 +176,23 @@ func (a aliasHandler) targetPathAlias(src string) (string, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Add the final touch
|
||||
// Add the final touch. When the alias does not already end in one of the
|
||||
// output format's configured suffixes, treat it as a directory and append
|
||||
// the format's base name and suffix (e.g. index.html).
|
||||
alias = strings.TrimPrefix(alias, "/")
|
||||
baseFile := of.BaseName + of.MediaType.FirstSuffix.FullSuffix
|
||||
if strings.HasSuffix(alias, "/") {
|
||||
alias = alias + "index.html"
|
||||
} else if !strings.HasSuffix(alias, ".html") {
|
||||
alias = alias + "/" + "index.html"
|
||||
alias = alias + baseFile
|
||||
} else if !pathHasOutputFormatSuffix(alias, of) {
|
||||
alias = alias + "/" + baseFile
|
||||
}
|
||||
|
||||
return filepath.FromSlash(alias), nil
|
||||
}
|
||||
|
||||
// pathHasOutputFormatSuffix reports whether the last element of p ends in one
|
||||
// of the suffixes configured for the output format's media type.
|
||||
func pathHasOutputFormatSuffix(p string, of output.Format) bool {
|
||||
ext := path.Ext(p)
|
||||
return ext != "" && of.MediaType.HasSuffix(ext[1:])
|
||||
}
|
||||
|
||||
+77
-1
@@ -21,6 +21,7 @@ import (
|
||||
|
||||
"github.com/gohugoio/hugo/common/loggers"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/output"
|
||||
)
|
||||
|
||||
func TestAlias(t *testing.T) {
|
||||
@@ -158,7 +159,7 @@ func TestTargetPathHTMLRedirectAlias(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
path, err := h.targetPathAlias(test.value)
|
||||
path, err := h.targetPathAlias(test.value, output.HTMLFormat)
|
||||
if (err == nil) != test.errIsNil {
|
||||
t.Errorf("Expected err == nil => %t, got: %t. err: %s", test.errIsNil, err == nil, err)
|
||||
continue
|
||||
@@ -789,3 +790,78 @@ build:
|
||||
b.AssertFileExists("public/p2-alias/index.html", false)
|
||||
b.AssertFileExists("public/p3-alias/index.html", false)
|
||||
}
|
||||
|
||||
// See issue 15066.
|
||||
func TestAliasExplicitExtension(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
|
||||
uglyURLs = UGLYURLS
|
||||
|
||||
[mediaTypes]
|
||||
[mediaTypes.'text/html']
|
||||
suffixes = SUFFIXES
|
||||
|
||||
[outputFormats]
|
||||
[outputFormats.html]
|
||||
mediaType = 'text/html'
|
||||
|
||||
-- content/s1/p1.md --
|
||||
---
|
||||
title: p1
|
||||
aliases: [a, b.foo, c.html, d.htm, e.foo.html, f.foo.htm]
|
||||
---
|
||||
-- layouts/page.html --
|
||||
{{ .Title }}
|
||||
`
|
||||
|
||||
r := strings.NewReplacer("UGLYURLS", "false", "SUFFIXES", "['html', 'htm']")
|
||||
f := r.Replace(files)
|
||||
|
||||
b := Test(t, f)
|
||||
|
||||
b.AssertFileContent("public/s1/a/index.html", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/b.foo/index.html", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/c.html", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/d.htm", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/e.foo.html", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/f.foo.htm", "url=/s1/p1/")
|
||||
|
||||
r = strings.NewReplacer("UGLYURLS", "false", "SUFFIXES", "['htm', 'html']")
|
||||
f = r.Replace(files)
|
||||
|
||||
b = Test(t, f)
|
||||
|
||||
b.AssertFileContent("public/s1/a/index.htm", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/b.foo/index.htm", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/c.html", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/d.htm", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/e.foo.html", "url=/s1/p1/")
|
||||
b.AssertFileContent("public/s1/f.foo.htm", "url=/s1/p1/")
|
||||
|
||||
r = strings.NewReplacer("UGLYURLS", "true", "SUFFIXES", "['html', 'htm']")
|
||||
f = r.Replace(files)
|
||||
|
||||
b = Test(t, f)
|
||||
|
||||
b.AssertFileContent("public/s1/a.html", "url=/s1/p1.html")
|
||||
b.AssertFileContent("public/s1/b.foo.html", "url=/s1/p1.html")
|
||||
b.AssertFileContent("public/s1/c.html", "url=/s1/p1.html")
|
||||
b.AssertFileContent("public/s1/d.htm", "url=/s1/p1.html")
|
||||
b.AssertFileContent("public/s1/e.foo.html", "url=/s1/p1.html")
|
||||
b.AssertFileContent("public/s1/f.foo.htm", "url=/s1/p1.html")
|
||||
|
||||
r = strings.NewReplacer("UGLYURLS", "true", "SUFFIXES", "['htm', 'html']")
|
||||
f = r.Replace(files)
|
||||
|
||||
b = Test(t, f)
|
||||
|
||||
b.AssertFileContent("public/s1/a.htm", "url=/s1/p1.htm")
|
||||
b.AssertFileContent("public/s1/b.foo.htm", "url=/s1/p1.htm")
|
||||
b.AssertFileContent("public/s1/c.html", "url=/s1/p1.htm")
|
||||
b.AssertFileContent("public/s1/d.htm", "url=/s1/p1.htm")
|
||||
b.AssertFileContent("public/s1/e.foo.html", "url=/s1/p1.htm")
|
||||
b.AssertFileContent("public/s1/f.foo.htm", "url=/s1/p1.htm")
|
||||
}
|
||||
|
||||
@@ -140,8 +140,8 @@ func (po *pageOutput) Aliases() []string {
|
||||
|
||||
a = path.Join(baseDir, a)
|
||||
|
||||
if conf.C.IsUglyURLSection(p.Section()) && !strings.HasSuffix(a, ".html") {
|
||||
a += ".html"
|
||||
if conf.C.IsUglyURLSection(p.Section()) && !pathHasOutputFormatSuffix(a, f) {
|
||||
a += f.MediaType.FirstSuffix.FullSuffix
|
||||
}
|
||||
|
||||
aliases[i] = a
|
||||
|
||||
Reference in New Issue
Block a user