hugolib, output: Incorporate suffix and type in layout resolve
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 7 Mar 2017 16:26:22 +0000 (17:26 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Mon, 27 Mar 2017 13:43:56 +0000 (15:43 +0200)
And remove some now superflous and hard to maintain tests.

hugolib/page_test.go
hugolib/path_separators_test.go
hugolib/site_output_test.go
output/layout.go
output/layout_test.go

index 82d6cbc8f6590aabda570027e9715c20171ee320..e7a26905da97a07aa9f7bc0fa30a08481f48ca26 100644 (file)
@@ -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 {
index bc1bcec0d497e6fed6a79e952b360b49f1e616e1..3a73869adc8bf1a5d85a4ea721b2fe812d81909b 100644 (file)
@@ -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)
-               }
-       }
-}
index e67818fb13fa5ac499a007d9e5f20d170352b31d..c449c65414b5593d0eb96ce37f4f60329a1cb07b 100644 (file)
@@ -21,6 +21,7 @@ import (
 )
 
 func TestDefaultOutputDefinitions(t *testing.T) {
+       t.Parallel()
        defs := defaultOutputDefinitions
 
        tests := []struct {
index 0e0f33dad44783cb468b63c4826079c79de00550..1d2cbeed0bc789953bfa02fbe5dd8440fbc52835 100644 (file)
@@ -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
 }
index 333216e17110e8de16ed3d2152798ff36875fd1c..8f851b8958f72a79a21f4c9573d0ffdcbeede0ef 100644 (file)
 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")
+                               }
                        }
-               }
+               })
        }
 }