ref: 4eb2fec67c3a72a3ac98aa834dc56fd4504626d8
parent: 83c761b71a980aee6331179b271c7e24e999e8eb
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Sat Jan 27 13:03:06 EST 2018
Fix handling of top-level page bundles Fixes #4332
--- a/create/content_template_handler.go
+++ b/create/content_template_handler.go
@@ -82,7 +82,7 @@
)
sp := source.NewSourceSpec(s.Deps.Cfg, s.Deps.Fs)
- f := sp.NewFileInfo("", targetPath, nil)+ f := sp.NewFileInfo("", targetPath, false, nil) data := ArchetypeFileData{Type: kind,
--- a/hugolib/fileInfo.go
+++ b/hugolib/fileInfo.go
@@ -57,7 +57,7 @@
func newFileInfo(sp *source.SourceSpec, baseDir, filename string, fi os.FileInfo, tp bundleDirType) *fileInfo {- baseFi := sp.NewFileInfo(baseDir, filename, fi)
+ baseFi := sp.NewFileInfo(baseDir, filename, tp == bundleLeaf, fi)
f := &fileInfo{bundleTp: tp,
ReadableFile: baseFi,
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -772,7 +772,7 @@
Keywords: []string{}, Sitemap: Sitemap{Priority: -1}, params: make(map[string]interface{}),translations: make(Pages, 0),
- sections: sectionsFromDir(fi.Dir()),
+ sections: sectionsFromFile(fi),
Site: &s.Info,
s: s,
}
@@ -2000,12 +2000,20 @@
return outfile
}
-func sectionsFromDir(dirname string) []string {+func sectionsFromFile(fi *fileInfo) []string {+ dirname := fi.Dir()
dirname = strings.Trim(dirname, helpers.FilePathSeparator)
if dirname == "" {return nil
}
- return strings.Split(dirname, helpers.FilePathSeparator)
+ parts := strings.Split(dirname, helpers.FilePathSeparator)
+
+ if fi.bundleTp == bundleLeaf && len(parts) > 0 {+ // my-section/mybundle/index.md => my-section
+ return parts[:len(parts)-1]
+ }
+
+ return parts
}
func kindFromFileInfo(fi *fileInfo) string {--- a/hugolib/page_bundler_capture_test.go
+++ b/hugolib/page_bundler_capture_test.go
@@ -143,8 +143,9 @@
D:
__bundle/en/work/base/_index.md/resources/en/work/base/_1.png
__bundle/en/work/base/a/b/index.md/resources/en/work/base/a/b/ab1.md
-__bundle/en/work/base/b/index.md/resources/en/work/base/b/1.md|en/work/base/b/2.md|en/work/base/b/c/logo.png|en/work/base/b/custom-mime.bep|en/work/base/b/sunset1.jpg|en/work/base/b/sunset2.jpg
-__bundle/en/work/base/c/index.md/resources/en/work/base/c/logo-은행.png
+__bundle/en/work/base/b/my-bundle/index.md/resources/en/work/base/b/my-bundle/1.md|en/work/base/b/my-bundle/2.md|en/work/base/b/my-bundle/c/logo.png|en/work/base/b/my-bundle/custom-mime.bep|en/work/base/b/my-bundle/sunset1.jpg|en/work/base/b/my-bundle/sunset2.jpg
+__bundle/en/work/base/c/bundle/index.md/resources/en/work/base/c/bundle/logo-은행.png
+__bundle/en/work/base/root/index.md/resources/en/work/base/root/1.md|en/work/base/root/c/logo.png
C:
/work/base/assets/pic1.png
/work/base/assets/pic2.png
--- a/hugolib/page_bundler_test.go
+++ b/hugolib/page_bundler_test.go
@@ -52,6 +52,7 @@
"a": ":sections/:filename",
"b": ":year/:slug/",
"c": ":sections/:slug",
+ "": ":filename/",
})
cfg.Set("outputFormats", map[string]interface{}{@@ -74,8 +75,7 @@
th := testHelper{s.Cfg, s.Fs, t}- // Singles (2), Below home (1), Bundle (1)
- assert.Len(s.RegularPages, 7)
+ assert.Len(s.RegularPages, 8)
singlePage := s.getPage(KindPage, "a/1.md")
@@ -99,11 +99,25 @@
// This should be just copied to destination.
th.assertFileContent(filepath.FromSlash("/work/public/assets/pic1.png"), "content")- leafBundle1 := s.getPage(KindPage, "b/index.md")
+ leafBundle1 := s.getPage(KindPage, "b/my-bundle/index.md")
assert.NotNil(leafBundle1)
+ assert.Equal("b", leafBundle1.Section())+ assert.NotNil(s.getPage(KindSection, "b"))
+
+ // This is a root bundle and should live in the "home section"
+ // See https://github.com/gohugoio/hugo/issues/4332
+ rootBundle := s.getPage(KindPage, "root")
+ assert.NotNil(rootBundle)
+ assert.True(rootBundle.Parent().IsHome())
+ if ugly {+ assert.Equal("/root.html", rootBundle.RelPermalink())+ } else {+ assert.Equal("/root/", rootBundle.RelPermalink())+ }
+
leafBundle2 := s.getPage(KindPage, "a/b/index.md")
assert.NotNil(leafBundle2)
- unicodeBundle := s.getPage(KindPage, "c/index.md")
+ unicodeBundle := s.getPage(KindPage, "c/bundle/index.md")
assert.NotNil(unicodeBundle)
pageResources := leafBundle1.Resources.ByType(pageResourceType)
@@ -110,9 +124,9 @@
assert.Len(pageResources, 2)
firstPage := pageResources[0].(*Page)
secondPage := pageResources[1].(*Page)
- assert.Equal(filepath.FromSlash("b/1.md"), firstPage.pathOrTitle(), secondPage.pathOrTitle())+ assert.Equal(filepath.FromSlash("b/my-bundle/1.md"), firstPage.pathOrTitle(), secondPage.pathOrTitle())assert.Contains(firstPage.Content, "TheContent")
- assert.Len(leafBundle1.Resources, 6) // 2 pages 3 images 1 custom mime type
+ assert.Equal(6, len(leafBundle1.Resources))
assert.Equal(firstPage, pageResources.GetByPrefix("1")) assert.Equal(secondPage, pageResources.GetByPrefix("2"))@@ -119,13 +133,13 @@
assert.Nil(pageResources.GetByPrefix("doesnotexist")) imageResources := leafBundle1.Resources.ByType("image")- assert.Len(imageResources, 3)
+ assert.Equal(3, len(imageResources))
image := imageResources[0]
altFormat := leafBundle1.OutputFormats().Get("CUSTOMO")assert.NotNil(altFormat)
- assert.Equal(filepath.FromSlash("/work/base/b/c/logo.png"), image.(resource.Source).AbsSourceFilename())+ assert.Equal(filepath.FromSlash("/work/base/b/my-bundle/c/logo.png"), image.(resource.Source).AbsSourceFilename()) assert.Equal("https://example.com/2017/pageslug/c/logo.png", image.Permalink()) th.assertFileContent(filepath.FromSlash("/work/public/2017/pageslug/c/logo.png"), "content") th.assertFileContent(filepath.FromSlash("/work/public/cpath/2017/pageslug/c/logo.png"), "content")@@ -161,6 +175,8 @@
assert.Equal("/2017/pageslug/", leafBundle1.RelPermalink()) th.assertFileContent(filepath.FromSlash("/work/public/2017/pageslug/index.html"), "TheContent") th.assertFileContent(filepath.FromSlash("/work/public/cpath/2017/pageslug/cindex.html"), "TheContent")+ th.assertFileContent(filepath.FromSlash("/work/public/2017/pageslug/index.html"), "Single Title")+ th.assertFileContent(filepath.FromSlash("/work/public/root/index.html"), "Single Title") assert.Equal("/a/b/", leafBundle2.RelPermalink())@@ -193,8 +209,8 @@
s := sites.Sites[0]
assert.Equal(8, len(s.RegularPages))
- assert.Equal(18, len(s.Pages))
- assert.Equal(35, len(s.AllPages))
+ assert.Equal(16, len(s.Pages))
+ assert.Equal(31, len(s.AllPages))
bundleWithSubPath := s.getPage(KindPage, "lb/index")
assert.NotNil(bundleWithSubPath)
@@ -269,9 +285,9 @@
s := sites.Sites[0]
assert.Equal(8, len(s.RegularPages))
- assert.Equal(18, len(s.Pages))
+ assert.Equal(16, len(s.Pages))
// No nn pages
- assert.Equal(18, len(s.AllPages))
+ assert.Equal(16, len(s.AllPages))
for _, p := range s.rawAllPages {assert.True(p.Lang() != "nn")
}
@@ -431,7 +447,7 @@
`
singleLayout := `
-Title: {{ .Title }}+Single Title: {{ .Title }} Content: {{ .Content }} {{ $sunset := .Resources.GetByPrefix "my-sunset-1" }} {{ with $sunset }}@@ -482,15 +498,15 @@
writeSource(t, fs, filepath.Join(workDir, "base", "assets", "pages", "mypage.md"), pageContent)
// Bundle
- writeSource(t, fs, filepath.Join(workDir, "base", "b", "index.md"), pageWithImageShortcodeAndResourceMetadataContent)
- writeSource(t, fs, filepath.Join(workDir, "base", "b", "1.md"), pageContent)
- writeSource(t, fs, filepath.Join(workDir, "base", "b", "2.md"), pageContent)
- writeSource(t, fs, filepath.Join(workDir, "base", "b", "custom-mime.bep"), "bepsays")
- writeSource(t, fs, filepath.Join(workDir, "base", "b", "c", "logo.png"), "content")
+ writeSource(t, fs, filepath.Join(workDir, "base", "b", "my-bundle", "index.md"), pageWithImageShortcodeAndResourceMetadataContent)
+ writeSource(t, fs, filepath.Join(workDir, "base", "b", "my-bundle", "1.md"), pageContent)
+ writeSource(t, fs, filepath.Join(workDir, "base", "b", "my-bundle", "2.md"), pageContent)
+ writeSource(t, fs, filepath.Join(workDir, "base", "b", "my-bundle", "custom-mime.bep"), "bepsays")
+ writeSource(t, fs, filepath.Join(workDir, "base", "b", "my-bundle", "c", "logo.png"), "content")
// Bundle with 은행 slug
// See https://github.com/gohugoio/hugo/issues/4241
- writeSource(t, fs, filepath.Join(workDir, "base", "c", "index.md"), `---
+ writeSource(t, fs, filepath.Join(workDir, "base", "c", "bundle", "index.md"), `---
title: "은행 은행"
slug: 은행
date: 2017-10-09
@@ -498,16 +514,22 @@
Content for 은행.
`)
- writeSource(t, fs, filepath.Join(workDir, "base", "c", "logo-은행.png"), "은행 PNG")
+ // Bundle in root
+ writeSource(t, fs, filepath.Join(workDir, "base", "root", "index.md"), pageWithImageShortcodeAndResourceMetadataContent)
+ writeSource(t, fs, filepath.Join(workDir, "base", "root", "1.md"), pageContent)
+ writeSource(t, fs, filepath.Join(workDir, "base", "root", "c", "logo.png"), "content")
+
+ writeSource(t, fs, filepath.Join(workDir, "base", "c", "bundle", "logo-은행.png"), "은행 PNG")
+
// Write a real image into one of the bundle above.
src, err := os.Open("testdata/sunset.jpg")assert.NoError(err)
// We need 2 to test https://github.com/gohugoio/hugo/issues/4202
- out, err := fs.Source.Create(filepath.Join(workDir, "base", "b", "sunset1.jpg"))
+ out, err := fs.Source.Create(filepath.Join(workDir, "base", "b", "my-bundle", "sunset1.jpg"))
assert.NoError(err)
- out2, err := fs.Source.Create(filepath.Join(workDir, "base", "b", "sunset2.jpg"))
+ out2, err := fs.Source.Create(filepath.Join(workDir, "base", "b", "my-bundle", "sunset2.jpg"))
assert.NoError(err)
_, err = io.Copy(out, src)
--- a/source/fileInfo.go
+++ b/source/fileInfo.go
@@ -54,6 +54,7 @@
LogicalName() string
// Section is first directory below the content root.
+ // For page bundles in root, the Section will be empty.
Section() string
// BaseFileName is a filename without extension.
@@ -99,6 +100,7 @@
baseName string
translationBaseName string
section string
+ isLeafBundle bool
uniqueID string
@@ -142,16 +144,12 @@
// in some cases that is slightly expensive to construct.
func (fi *FileInfo) init() { fi.lazyInit.Do(func() {- parts := strings.Split(fi.relDir, helpers.FilePathSeparator)
+ relDir := strings.Trim(fi.relDir, helpers.FilePathSeparator)
+ parts := strings.Split(relDir, helpers.FilePathSeparator)
+
var section string
- if len(parts) == 1 {+ if (!fi.isLeafBundle && len(parts) == 1) || len(parts) > 1 {section = parts[0]
- } else if len(parts) > 1 {- if parts[0] == "" {- section = parts[1]
- } else {- section = parts[0]
- }
}
fi.section = section
@@ -161,7 +159,7 @@
})
}
-func (sp *SourceSpec) NewFileInfo(baseDir, filename string, fi os.FileInfo) *FileInfo {+func (sp *SourceSpec) NewFileInfo(baseDir, filename string, isLeafBundle bool, fi os.FileInfo) *FileInfo {dir, name := filepath.Split(filename)
if !strings.HasSuffix(dir, helpers.FilePathSeparator) {@@ -204,6 +202,7 @@
name: name,
baseName: baseName,
translationBaseName: translationBaseName,
+ isLeafBundle: isLeafBundle,
}
return f
--- a/source/fileInfo_test.go
+++ b/source/fileInfo_test.go
@@ -34,10 +34,15 @@
assert.Equal(filepath.FromSlash("/a/b/page.md"), f.Filename()) assert.Equal(filepath.FromSlash("b/"), f.Dir()) assert.Equal(filepath.FromSlash("b/page.md"), f.Path())+ assert.Equal("b", f.Section())}},
+ {filepath.FromSlash("/a/"), filepath.FromSlash("/a/b/c/d/page.md"), func(f *FileInfo) {+ assert.Equal("b", f.Section())+
+ }},
} {- f := s.NewFileInfo(this.base, this.filename, nil)
+ f := s.NewFileInfo(this.base, this.filename, false, nil)
this.assert(f)
}
--- a/source/filesystem.go
+++ b/source/filesystem.go
@@ -57,7 +57,7 @@
name = norm.NFC.String(name)
}
- file = f.SourceSpec.NewFileInfo(f.Base, name, fi)
+ file = f.SourceSpec.NewFileInfo(f.Base, name, false, fi)
f.files = append(f.files, file)
return err
--
⑨