URI: 
       hugolib, output: Incorporate suffix and type in layout resolve - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 3ec5fc35043639e7592819014180666b1a8e926b
   DIR parent f091fc23edfa912ae3e6e2d3a80d65432db6e35e
  HTML Author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
       Date:   Tue,  7 Mar 2017 17:26:22 +0100
       
       hugolib, output: Incorporate suffix and type in layout resolve
       
       And remove some now superflous and hard to maintain tests.
       
       Diffstat:
         M hugolib/page_test.go                |      60 +++----------------------------
         M hugolib/path_separators_test.go     |      33 -------------------------------
         M hugolib/site_output_test.go         |       1 +
         M output/layout.go                    |      61 ++++++++++++++++++++++++-------
         M output/layout_test.go               |      73 ++++++++++++++++++-------------
       
       5 files changed, 95 insertions(+), 133 deletions(-)
       ---
   DIR diff --git a/hugolib/page_test.go b/hugolib/page_test.go
       @@ -659,7 +659,11 @@ func TestCreateNewPage(t *testing.T) {
                        checkPageContent(t, p, normalizeExpected(ext, "<p>Simple Page</p>\n"))
                        checkPageSummary(t, p, "Simple Page")
                        checkPageType(t, p, "page")
       -                checkPageLayout(t, p, "page/single.html", "_default/single.html", "theme/page/single.html", "theme/_default/single.html")
       +                checkPageLayout(t, p,
       +                        "page/single.html.html", "page/single.html",
       +                        "_default/single.html.html", "_default/single.html",
       +                        "theme/page/single.html.html", "theme/page/single.html",
       +                        "theme/_default/single.html.html", "theme/_default/single.html")
                        checkTruncation(t, p, false, "simple short page")
                }
        
       @@ -729,7 +733,6 @@ func TestPageWithDelimiter(t *testing.T) {
                        checkPageContent(t, p, normalizeExpected(ext, "<p>Summary Next Line</p>\n\n<p>Some more text</p>\n"), ext)
                        checkPageSummary(t, p, normalizeExpected(ext, "<p>Summary Next Line</p>"), ext)
                        checkPageType(t, p, "page")
       -                checkPageLayout(t, p, "page/single.html", "_default/single.html", "theme/page/single.html", "theme/_default/single.html")
                        checkTruncation(t, p, true, "page with summary delimiter")
                }
        
       @@ -787,7 +790,6 @@ func TestPageWithShortCodeInSummary(t *testing.T) {
                        checkPageContent(t, p, normalizeExpected(ext, "<p>Summary Next Line. \n<figure >\n    \n        <img src=\"/not/real\" />\n    \n    \n</figure>\n.\nMore text here.</p>\n\n<p>Some more text</p>\n"))
                        checkPageSummary(t, p, "Summary Next Line.  . More text here. Some more text")
                        checkPageType(t, p, "page")
       -                checkPageLayout(t, p, "page/single.html", "_default/single.html", "theme/page/single.html", "theme/_default/single.html")
                }
        
                testAllMarkdownEnginesForPages(t, assertFunc, nil, simplePageWithShortcodeInSummary)
       @@ -846,7 +848,6 @@ func TestPageWithMoreTag(t *testing.T) {
                        checkPageContent(t, p, normalizeExpected(ext, "<p>Summary Same Line</p>\n\n<p>Some more text</p>\n"))
                        checkPageSummary(t, p, normalizeExpected(ext, "<p>Summary Same Line</p>"))
                        checkPageType(t, p, "page")
       -                checkPageLayout(t, p, "page/single.html", "_default/single.html", "theme/page/single.html", "theme/_default/single.html")
        
                }
        
       @@ -1103,57 +1104,6 @@ func L(s ...string) []string {
                return s
        }
        
       -func TestLayoutOverride(t *testing.T) {
       -        t.Parallel()
       -        var (
       -                pathContentTwoDir = filepath.Join("content", "dub", "sub", "file1.md")
       -                pathContentOneDir = filepath.Join("content", "gub", "file1.md")
       -                pathContentNoDir  = filepath.Join("content", "file1")
       -                pathOneDirectory  = filepath.Join("fub", "file1.md")
       -                pathNoDirectory   = filepath.Join("file1.md")
       -        )
       -        tests := []struct {
       -                content        string
       -                path           string
       -                expectedLayout []string
       -        }{
       -                {simplePageNoLayout, pathContentTwoDir, L("dub/single.html", "_default/single.html")},
       -                {simplePageNoLayout, pathContentOneDir, L("gub/single.html", "_default/single.html")},
       -                {simplePageNoLayout, pathContentNoDir, L("page/single.html", "_default/single.html")},
       -                {simplePageNoLayout, pathOneDirectory, L("fub/single.html", "_default/single.html")},
       -                {simplePageNoLayout, pathNoDirectory, L("page/single.html", "_default/single.html")},
       -                {simplePageLayoutFoobar, pathContentTwoDir, L("dub/foobar.html", "_default/foobar.html")},
       -                {simplePageLayoutFoobar, pathContentOneDir, L("gub/foobar.html", "_default/foobar.html")},
       -                {simplePageLayoutFoobar, pathOneDirectory, L("fub/foobar.html", "_default/foobar.html")},
       -                {simplePageLayoutFoobar, pathNoDirectory, L("page/foobar.html", "_default/foobar.html")},
       -                {simplePageTypeFoobar, pathContentTwoDir, L("foobar/single.html", "_default/single.html")},
       -                {simplePageTypeFoobar, pathContentOneDir, L("foobar/single.html", "_default/single.html")},
       -                {simplePageTypeFoobar, pathContentNoDir, L("foobar/single.html", "_default/single.html")},
       -                {simplePageTypeFoobar, pathOneDirectory, L("foobar/single.html", "_default/single.html")},
       -                {simplePageTypeFoobar, pathNoDirectory, L("foobar/single.html", "_default/single.html")},
       -                {simplePageTypeLayout, pathContentTwoDir, L("barfoo/buzfoo.html", "_default/buzfoo.html")},
       -                {simplePageTypeLayout, pathContentOneDir, L("barfoo/buzfoo.html", "_default/buzfoo.html")},
       -                {simplePageTypeLayout, pathContentNoDir, L("barfoo/buzfoo.html", "_default/buzfoo.html")},
       -                {simplePageTypeLayout, pathOneDirectory, L("barfoo/buzfoo.html", "_default/buzfoo.html")},
       -                {simplePageTypeLayout, pathNoDirectory, L("barfoo/buzfoo.html", "_default/buzfoo.html")},
       -        }
       -        for _, test := range tests {
       -                s := newTestSite(t)
       -                p, _ := s.NewPage(test.path)
       -                _, err := p.ReadFrom(strings.NewReader(test.content))
       -                if err != nil {
       -                        t.Fatalf("Unable to parse content:\n%s\n", test.content)
       -                }
       -
       -                for _, y := range test.expectedLayout {
       -                        test.expectedLayout = append(test.expectedLayout, "theme/"+y)
       -                }
       -                if !listEqual(p.layouts(), test.expectedLayout) {
       -                        t.Errorf("Layout mismatch. Expected: %s, got: %s", test.expectedLayout, p.layouts())
       -                }
       -        }
       -}
       -
        func TestSliceToLower(t *testing.T) {
                t.Parallel()
                tests := []struct {
   DIR diff --git a/hugolib/path_separators_test.go b/hugolib/path_separators_test.go
       @@ -36,36 +36,3 @@ func TestDegenerateMissingFolderInPageFilename(t *testing.T) {
                        t.Fatalf("No section should be set for a file path: foobar")
                }
        }
       -
       -func TestNewPageWithFilePath(t *testing.T) {
       -        t.Parallel()
       -        s := newTestSite(t)
       -        toCheck := []struct {
       -                input   string
       -                section string
       -                layout  []string
       -        }{
       -                {filepath.Join("sub", "foobar.html"), "sub", L("sub/single.html", "_default/single.html")},
       -                {filepath.Join("content", "foobar.html"), "", L("page/single.html", "_default/single.html")},
       -                {filepath.Join("content", "sub", "foobar.html"), "sub", L("sub/single.html", "_default/single.html")},
       -                {filepath.Join("content", "dub", "sub", "foobar.html"), "dub", L("dub/single.html", "_default/single.html")},
       -        }
       -
       -        for i, el := range toCheck {
       -                p, err := s.NewPageFrom(strings.NewReader(simplePageYAML), el.input)
       -                if err != nil {
       -                        t.Errorf("[%d] Reading from simplePageYAML resulted in an error: %s", i, err)
       -                }
       -                if p.Section() != el.section {
       -                        t.Errorf("[%d] Section incorrect page %s. got %s but expected %s", i, el.input, p.Section(), el.section)
       -                }
       -
       -                for _, y := range el.layout {
       -                        el.layout = append(el.layout, "theme/"+y)
       -                }
       -
       -                if !listEqual(p.layouts(), el.layout) {
       -                        t.Errorf("[%d] Layout incorrect. got '%s' but expected '%s'", i, p.layouts(), el.layout)
       -                }
       -        }
       -}
   DIR diff --git a/hugolib/site_output_test.go b/hugolib/site_output_test.go
       @@ -21,6 +21,7 @@ import (
        )
        
        func TestDefaultOutputDefinitions(t *testing.T) {
       +        t.Parallel()
                defs := defaultOutputDefinitions
        
                tests := []struct {
   DIR diff --git a/output/layout.go b/output/layout.go
       @@ -37,12 +37,27 @@ func NewLayoutHandler(hasTheme bool) *LayoutHandler {
                return &LayoutHandler{hasTheme: hasTheme}
        }
        
       -// TODO(bep) output theme layouts
       -var (
       -        layoutsHome        = "index.html _default/list.html"
       -        layoutsSection     = "section/SECTION.html  SECTION/list.html _default/section.html _default/list.html indexes/SECTION.html _default/indexes.html"
       -        layoutTaxonomy     = "taxonomy/SECTION.html indexes/SECTION.html _default/taxonomy.html _default/list.html"
       -        layoutTaxonomyTerm = "taxonomy/SECTION.terms.html _default/terms.html indexes/indexes.html"
       +const (
       +        layoutsHome    = "index.NAME.SUFFIX index.SUFFIX _default/list.NAME.SUFFIX _default/list.SUFFIX"
       +        layoutsSection = `
       +section/SECTION.NAME.SUFFIX section/SECTION.SUFFIX
       +SECTION/list.NAME.SUFFIX SECTION/list.SUFFIX
       +_default/section.NAME.SUFFIX _default/section.SUFFIX
       +_default/list.NAME.SUFFIX _default/list.SUFFIX
       +indexes/SECTION.NAME.SUFFIX indexes/SECTION.SUFFIX
       +_default/indexes.NAME.SUFFIX _default/indexes.SUFFIX
       +`
       +        layoutTaxonomy = `
       +taxonomy/SECTION.NAME.SUFFIX taxonomy/SECTION.SUFFIX
       +indexes/SECTION.NAME.SUFFIX indexes/SECTION.SUFFIX 
       +_default/taxonomy.NAME.SUFFIX _default/taxonomy.SUFFIX
       +_default/list.NAME.SUFFIX _default/list.SUFFIX
       +`
       +        layoutTaxonomyTerm = `
       +taxonomy/SECTION.terms.NAME.SUFFIX taxonomy/SECTION.terms.SUFFIX
       +_default/terms.NAME.SUFFIX _default/terms.SUFFIX
       +indexes/indexes.NAME.SUFFIX indexes/indexes.SUFFIX
       +`
        )
        
        func (l *LayoutHandler) For(id LayoutIdentifier, layoutOverride string, tp Type) []string {
       @@ -57,15 +72,15 @@ func (l *LayoutHandler) For(id LayoutIdentifier, layoutOverride string, tp Type)
                switch id.PageKind() {
                // TODO(bep) move the Kind constants some common place.
                case "home":
       -                layouts = strings.Fields(layoutsHome)
       +                layouts = resolveTemplate(layoutsHome, id, tp)
                case "section":
       -                layouts = strings.Fields(strings.Replace(layoutsSection, "SECTION", id.PageSection(), -1))
       +                layouts = resolveTemplate(layoutsSection, id, tp)
                case "taxonomy":
       -                layouts = strings.Fields(strings.Replace(layoutTaxonomy, "SECTION", id.PageSection(), -1))
       +                layouts = resolveTemplate(layoutTaxonomy, id, tp)
                case "taxonomyTerm":
       -                layouts = strings.Fields(strings.Replace(layoutTaxonomyTerm, "SECTION", id.PageSection(), -1))
       +                layouts = resolveTemplate(layoutTaxonomyTerm, id, tp)
                case "page":
       -                layouts = regularPageLayouts(id.PageType(), layout)
       +                layouts = regularPageLayouts(id.PageType(), layout, tp)
                }
        
                if l.hasTheme {
       @@ -97,23 +112,41 @@ func (l *LayoutHandler) For(id LayoutIdentifier, layoutOverride string, tp Type)
                return layouts
        }
        
       -func regularPageLayouts(types string, layout string) (layouts []string) {
       +func resolveTemplate(templ string, id LayoutIdentifier, tp Type) []string {
       +        return strings.Fields(replaceKeyValues(templ,
       +                "SUFFIX", tp.MediaType.Suffix,
       +                "NAME", strings.ToLower(tp.Name),
       +                "SECTION", id.PageSection()))
       +}
       +
       +func replaceKeyValues(s string, oldNew ...string) string {
       +        replacer := strings.NewReplacer(oldNew...)
       +        return replacer.Replace(s)
       +}
       +
       +func regularPageLayouts(types string, layout string, tp Type) (layouts []string) {
                if layout == "" {
                        layout = "single"
                }
        
       +        suffix := tp.MediaType.Suffix
       +        name := strings.ToLower(tp.Name)
       +
                if types != "" {
                        t := strings.Split(types, "/")
        
                        // Add type/layout.html
                        for i := range t {
                                search := t[:len(t)-i]
       -                        layouts = append(layouts, fmt.Sprintf("%s/%s.html", strings.ToLower(path.Join(search...)), layout))
       +                        layouts = append(layouts, fmt.Sprintf("%s/%s.%s.%s", strings.ToLower(path.Join(search...)), layout, name, suffix))
       +                        layouts = append(layouts, fmt.Sprintf("%s/%s.%s", strings.ToLower(path.Join(search...)), layout, suffix))
       +
                        }
                }
        
                // Add _default/layout.html
       -        layouts = append(layouts, fmt.Sprintf("_default/%s.html", layout))
       +        layouts = append(layouts, fmt.Sprintf("_default/%s.%s.%s", layout, name, suffix))
       +        layouts = append(layouts, fmt.Sprintf("_default/%s.%s", layout, suffix))
        
                return
        }
   DIR diff --git a/output/layout_test.go b/output/layout_test.go
       @@ -14,9 +14,10 @@
        package output
        
        import (
       -        "fmt"
                "testing"
        
       +        "github.com/spf13/hugo/media"
       +
                "github.com/stretchr/testify/require"
        )
        
       @@ -43,46 +44,56 @@ func (l testLayoutIdentifier) PageSection() string {
                return l.pageSection
        }
        
       +var ampType = Type{
       +        Name:      "AMP",
       +        MediaType: media.HTMLType,
       +        BaseName:  "index",
       +}
       +
        func TestLayout(t *testing.T) {
        
       -        for i, this := range []struct {
       +        for _, this := range []struct {
       +                name           string
                        li             testLayoutIdentifier
                        hasTheme       bool
                        layoutOverride string
                        tp             Type
                        expect         []string
                }{
       -                {testLayoutIdentifier{"home", "", "", ""}, true, "", HTMLType,
       -                        []string{"index.html", "_default/list.html", "theme/index.html", "theme/_default/list.html"}},
       -                {testLayoutIdentifier{"section", "sect1", "", ""}, false, "", HTMLType,
       -                        []string{"section/sect1.html", "sect1/list.html"}},
       -                {testLayoutIdentifier{"taxonomy", "tag", "", ""}, false, "", HTMLType,
       -                        []string{"taxonomy/tag.html", "indexes/tag.html"}},
       -                {testLayoutIdentifier{"taxonomyTerm", "categories", "", ""}, false, "", HTMLType,
       -                        []string{"taxonomy/categories.terms.html", "_default/terms.html"}},
       -                {testLayoutIdentifier{"page", "", "", ""}, true, "", HTMLType,
       -                        []string{"_default/single.html", "theme/_default/single.html"}},
       -                {testLayoutIdentifier{"page", "", "mylayout", ""}, false, "", HTMLType,
       -                        []string{"_default/mylayout.html"}},
       -                {testLayoutIdentifier{"page", "", "mylayout", "myttype"}, false, "", HTMLType,
       -                        []string{"myttype/mylayout.html", "_default/mylayout.html"}},
       -                {testLayoutIdentifier{"page", "", "mylayout", "myttype/mysubtype"}, false, "", HTMLType,
       -                        []string{"myttype/mysubtype/mylayout.html", "myttype/mylayout.html", "_default/mylayout.html"}},
       -                {testLayoutIdentifier{"page", "", "mylayout", "myttype"}, false, "myotherlayout", HTMLType,
       -                        []string{"myttype/myotherlayout.html", "_default/myotherlayout.html"}},
       +                {"Home", testLayoutIdentifier{"home", "", "", ""}, true, "", ampType,
       +                        []string{"index.amp.html", "index.html", "_default/list.amp.html", "_default/list.html", "theme/index.amp.html", "theme/index.html"}},
       +                {"Section", testLayoutIdentifier{"section", "sect1", "", ""}, false, "", ampType,
       +                        []string{"section/sect1.amp.html", "section/sect1.html"}},
       +                {"Taxonomy", testLayoutIdentifier{"taxonomy", "tag", "", ""}, false, "", ampType,
       +                        []string{"taxonomy/tag.amp.html", "taxonomy/tag.html"}},
       +                {"Taxonomy term", testLayoutIdentifier{"taxonomyTerm", "categories", "", ""}, false, "", ampType,
       +                        []string{"taxonomy/categories.terms.amp.html", "taxonomy/categories.terms.html", "_default/terms.amp.html"}},
       +                {"Page", testLayoutIdentifier{"page", "", "", ""}, true, "", ampType,
       +                        []string{"_default/single.amp.html", "_default/single.html", "theme/_default/single.amp.html"}},
       +                {"Page with layout", testLayoutIdentifier{"page", "", "mylayout", ""}, false, "", ampType,
       +                        []string{"_default/mylayout.amp.html", "_default/mylayout.html"}},
       +                {"Page with layout and type", testLayoutIdentifier{"page", "", "mylayout", "myttype"}, false, "", ampType,
       +                        []string{"myttype/mylayout.amp.html", "myttype/mylayout.html", "_default/mylayout.amp.html"}},
       +                {"Page with layout and type with subtype", testLayoutIdentifier{"page", "", "mylayout", "myttype/mysubtype"}, false, "", ampType,
       +                        []string{"myttype/mysubtype/mylayout.amp.html", "myttype/mysubtype/mylayout.html", "myttype/mylayout.amp.html"}},
       +                {"Page with overridden layout", testLayoutIdentifier{"page", "", "mylayout", "myttype"}, false, "myotherlayout", ampType,
       +                        []string{"myttype/myotherlayout.amp.html", "myttype/myotherlayout.html"}},
                } {
       -                l := NewLayoutHandler(this.hasTheme)
       -                logMsg := fmt.Sprintf("Test %d", i)
       -                layouts := l.For(this.li, this.layoutOverride, this.tp)
       -                require.NotNil(t, layouts, logMsg)
       -                require.True(t, len(layouts) >= len(this.expect), logMsg)
       -                // Not checking the complete list for now ...
       -                require.Equal(t, this.expect, layouts[:len(this.expect)], logMsg)
       +                t.Run(this.name, func(t *testing.T) {
       +                        l := NewLayoutHandler(this.hasTheme)
       +
       +                        layouts := l.For(this.li, this.layoutOverride, this.tp)
       +
       +                        require.NotNil(t, layouts)
       +                        require.True(t, len(layouts) >= len(this.expect))
       +                        // Not checking the complete list for now ...
       +                        require.Equal(t, this.expect, layouts[:len(this.expect)])
        
       -                if !this.hasTheme {
       -                        for _, layout := range layouts {
       -                                require.NotContains(t, layout, "theme", logMsg)
       +                        if !this.hasTheme {
       +                                for _, layout := range layouts {
       +                                        require.NotContains(t, layout, "theme")
       +                                }
                                }
       -                }
       +                })
                }
        }