diff --git a/hugolib/alias.go b/hugolib/alias.go index 58d908ce6..32058833e 100644 --- a/hugolib/alias.go +++ b/hugolib/alias.go @@ -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:]) +} diff --git a/hugolib/alias_test.go b/hugolib/alias_test.go index 977c6d9e1..e9bfe8e6c 100644 --- a/hugolib/alias_test.go +++ b/hugolib/alias_test.go @@ -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") +} diff --git a/hugolib/page__output.go b/hugolib/page__output.go index 979fb755b..384ed5f9e 100644 --- a/hugolib/page__output.go +++ b/hugolib/page__output.go @@ -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