Skip to content

Commit fea4fd8

Browse files
committed
hugolib: Avoid index.md in /index/index.html
Hugo 0.20 broke some sites that grouped their blog post and images together in subfolders. This commit re-introduces that behaviour: * If the file base name resolves to the same as the base name for the output type (i.e. "index" for HTML), the user probably meant it, so we treat that as an `uglyURL`, i.e. `my-blog-post-1.md`=> `/my-blog-post-1/index.html` * The main use case for this is to group blog post and images together. * Note that for the top level folder there will be a potential name conflict with a `section` `index.html` (if enabled) * This issue will not be relevant for subfolders in sections * Hugo will soon add support for nested sections, but we will have to find a way to separate them from the rest (`/content/_mysubsection` maybe). Fixes #3396
1 parent 656f818 commit fea4fd8

File tree

3 files changed

+32
-7
lines changed

3 files changed

+32
-7
lines changed

‎hugolib/page_paths.go‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,15 @@ func createTargetPath(d targetPathDescriptor) string {
141141

142142
isUgly := d.UglyURLs && !d.Type.NoUgly
143143

144+
// If the page output format's base name is the same as the page base name,
145+
// we treat it as an ugly path, i.e.
146+
// my-blog-post-1/index.md => my-blog-post-1/index.html
147+
// (given the default values for that content file, i.e. no slug set etc.).
148+
// This introduces the behaviour from < Hugo 0.20, see issue #3396.
149+
if d.BaseName != "" && d.BaseName == d.Type.BaseName {
150+
isUgly = true
151+
}
152+
144153
if d.Kind != KindPage && len(d.Sections) > 0 {
145154
pagePath = filepath.Join(d.Sections...)
146155
needsBase = false

‎hugolib/page_paths_test.go‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ func TestPageTargetPath(t *testing.T) {
6262
BaseName: "mypage",
6363
Sections: []string{"a"},
6464
Type: output.HTMLFormat}, "/a/b/mypage/index.html"},
65+
66+
{
67+
// Issue #3396
68+
"HTML page with index as base", targetPathDescriptor{
69+
Kind: KindPage,
70+
Dir: "/a/b",
71+
BaseName: "index",
72+
Sections: []string{"a"},
73+
Type: output.HTMLFormat}, "/a/b/index.html"},
74+
6575
{
6676
"HTML page with special chars", targetPathDescriptor{
6777
Kind: KindPage,
@@ -139,7 +149,9 @@ func TestPageTargetPath(t *testing.T) {
139149
expected := test.expected
140150

141151
// TODO(bep) simplify
142-
if test.d.Kind == KindHome && test.d.Type.Path != "" {
152+
if test.d.BaseName == test.d.Type.BaseName {
153+
154+
} else if test.d.Kind == KindHome && test.d.Type.Path != "" {
143155
} else if (!strings.HasPrefix(expected, "/index") || test.d.Addends != "") && test.d.URL == "" && isUgly {
144156
expected = strings.Replace(expected,
145157
"/"+test.d.Type.BaseName+"."+test.d.Type.MediaType.Suffix,

‎hugolib/site_test.go‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -959,11 +959,13 @@ func TestRefLinking(t *testing.T) {
959959
}{
960960
// Note: There are no magic in the index.md name. This was fixed in Hugo 0.20.
961961
// Before that, index.md would wrongly resolve to "/".
962-
{"index.md", "", true, "/index/"},
962+
// See #3396 -- there is an ambiguity in the examples below, even if they do work.
963+
// TODO(bep) better test cases
964+
{"index.md", "", true, "/"},
963965
{"common.md", "", true, "/level2/common/"},
964966
{"3-root.md", "", true, "/level2/level3/3-root/"},
965-
{"index.md", "amp", true, "/amp/index/"},
966-
{"index.md", "amp", false, "http://auth/amp/index/"},
967+
{"index.md", "amp", true, "/amp/"},
968+
{"index.md", "amp", false, "http://auth/amp/"},
967969
} {
968970
if out, err := site.Info.refLink(test.link, currentPage, test.relative, test.outputFormat); err != nil || out != test.expected {
969971
t.Errorf("[%d] Expected %s to resolve to (%s), got (%s) - error: %s", i, test.link, test.expected, out, err)
@@ -981,9 +983,11 @@ func TestSourceRelativeLinksing(t *testing.T) {
981983

982984
okresults := map[string]resultMap{
983985
"index.md": map[string]string{
984-
"/docs/rootfile.md": "/rootfile/",
985-
"rootfile.md": "/rootfile/",
986-
"index.md": "/index/",
986+
"/docs/rootfile.md": "/rootfile/",
987+
"rootfile.md": "/rootfile/",
988+
// See #3396 -- this may potentially be ambiguous (i.e. name conflict with home page).
989+
// But the user have chosen so. This index.md patterns is more relevant in /sub-folders.
990+
"index.md": "/",
987991
"level2/2-root.md": "/level2/2-root/",
988992
"/docs/level2/2-root.md": "/level2/2-root/",
989993
"level2/level3/3-root.md": "/level2/level3/3-root/",

0 commit comments

Comments
 (0)