Permalink
Browse files

layout: Respect Type and Layout for list template selection

This commit also has some other nice side-effects:

* The layout logic is unified for all page types, which should make it less surprising
* Page.Render now supports all types
* The legacy "indexes" type is removed from the template lookup order. This is an undocumented type from early Hugo days. This means that having a template in, say, `/layouts/indexes/list.html` will no longer work.
* The theme override logic is improved. As an example, an `index.html` in theme will now wn over a `_default/list.html` in the project, which most will expect.

Fixes #3005
Fixes #3245
  • Loading branch information...
bep committed Jan 13, 2018
1 parent b6ea6d0 commit 51dd462c3958f7cf032b06503f1f200a6aceebb9
Showing with 216 additions and 221 deletions.
  1. +5 −22 hugolib/page_output.go
  2. +1 −1 hugolib/site.go
  3. +0 −1 hugolib/site_render.go
  4. +16 −17 output/docshelper.go
  5. +148 −152 output/layout.go
  6. +46 −28 output/layout_test.go
@@ -100,22 +100,19 @@ func (p *PageOutput) layouts(layouts ...string) ([]string, error) {
return []string{p.selfLayout}, nil
}
layoutOverride := ""
layoutDescriptor := p.layoutDescriptor
if len(layouts) > 0 {
layoutOverride = layouts[0]
layoutDescriptor.Layout = layouts[0]
layoutDescriptor.LayoutOverride = true
}
return p.s.layoutHandler.For(
p.layoutDescriptor,
layoutOverride,
layoutDescriptor,
p.outputFormat)
}
func (p *PageOutput) Render(layout ...string) template.HTML {
if !p.checkRender() {
return ""
}
l, err := p.layouts(layout...)
if err != nil {
helpers.DistinctErrorLog.Printf("in .Render: Failed to resolve layout %q for page %q", layout, p.pathOrTitle())
@@ -145,10 +142,6 @@ func (p *PageOutput) Render(layout ...string) template.HTML {
}
func (p *Page) Render(layout ...string) template.HTML {
if !p.checkRender() {
return ""
}
p.pageOutputInit.Do(func() {
if p.mainPageOutput != nil {
return
@@ -170,16 +163,6 @@ func (p *Page) Render(layout ...string) template.HTML {
return p.mainPageOutput.Render(layout...)
}
// We may fix this in the future, but the layout handling in Render isn't built
// for list pages.
func (p *Page) checkRender() bool {
if p.Kind != KindPage {
helpers.DistinctWarnLog.Printf(".Render only available for regular pages, not for of kind %q. You probably meant .Site.RegularPages and not.Site.Pages.", p.Kind)
return false
}
return true
}
// OutputFormats holds a list of the relevant output formats for a given resource.
type OutputFormats []*OutputFormat
@@ -1541,7 +1541,7 @@ func (s *Site) kindFromSections(sections []string) string {
}
func (s *Site) layouts(p *PageOutput) ([]string, error) {
return s.layoutHandler.For(p.layoutDescriptor, "", p.outputFormat)
return s.layoutHandler.For(p.layoutDescriptor, p.outputFormat)
}
func (s *Site) preparePages() error {
@@ -242,7 +242,6 @@ func (s *Site) renderRSS(p *PageOutput) error {
layouts, err := s.layoutHandler.For(
p.layoutDescriptor,
"",
p.outputFormat)
if err != nil {
return err
@@ -37,27 +37,26 @@ func createLayoutExamples() interface{} {
)
for _, example := range []struct {
name string
d LayoutDescriptor
hasTheme bool
layoutOverride string
f Format
name string
d LayoutDescriptor
hasTheme bool
f Format
}{
{`AMP home, with theme "demoTheme".`, LayoutDescriptor{Kind: "home"}, true, "", AMPFormat},
{`AMP home, French language".`, LayoutDescriptor{Kind: "home", Lang: "fr"}, false, "", AMPFormat},
{"RSS home, no theme.", LayoutDescriptor{Kind: "home"}, false, "", RSSFormat},
{"JSON home, no theme.", LayoutDescriptor{Kind: "home"}, false, "", JSONFormat},
{fmt.Sprintf(`CSV regular, "layout: %s" in front matter.`, demoLayout), LayoutDescriptor{Kind: "page", Layout: demoLayout}, false, "", CSVFormat},
{fmt.Sprintf(`JSON regular, "type: %s" in front matter.`, demoType), LayoutDescriptor{Kind: "page", Type: demoType}, false, "", JSONFormat},
{"HTML regular.", LayoutDescriptor{Kind: "page"}, false, "", HTMLFormat},
{"AMP regular.", LayoutDescriptor{Kind: "page"}, false, "", AMPFormat},
{"Calendar blog section.", LayoutDescriptor{Kind: "section", Section: "blog"}, false, "", CalendarFormat},
{"Calendar taxonomy list.", LayoutDescriptor{Kind: "taxonomy", Section: "tag"}, false, "", CalendarFormat},
{"Calendar taxonomy term.", LayoutDescriptor{Kind: "taxonomyTerm", Section: "tag"}, false, "", CalendarFormat},
{`AMP home, with theme "demoTheme".`, LayoutDescriptor{Kind: "home"}, true, AMPFormat},
{`AMP home, French language".`, LayoutDescriptor{Kind: "home", Lang: "fr"}, false, AMPFormat},
{"RSS home, no theme.", LayoutDescriptor{Kind: "home"}, false, RSSFormat},
{"JSON home, no theme.", LayoutDescriptor{Kind: "home"}, false, JSONFormat},
{fmt.Sprintf(`CSV regular, "layout: %s" in front matter.`, demoLayout), LayoutDescriptor{Kind: "page", Layout: demoLayout}, false, CSVFormat},
{fmt.Sprintf(`JSON regular, "type: %s" in front matter.`, demoType), LayoutDescriptor{Kind: "page", Type: demoType}, false, JSONFormat},
{"HTML regular.", LayoutDescriptor{Kind: "page"}, false, HTMLFormat},
{"AMP regular.", LayoutDescriptor{Kind: "page"}, false, AMPFormat},
{"Calendar blog section.", LayoutDescriptor{Kind: "section", Section: "blog"}, false, CalendarFormat},
{"Calendar taxonomy list.", LayoutDescriptor{Kind: "taxonomy", Section: "tag"}, false, CalendarFormat},
{"Calendar taxonomy term.", LayoutDescriptor{Kind: "taxonomyTerm", Section: "tag"}, false, CalendarFormat},
} {
l := NewLayoutHandler(example.hasTheme)
layouts, _ := l.For(example.d, example.layoutOverride, example.f)
layouts, _ := l.For(example.d, example.f)
basicExamples = append(basicExamples, Example{
Example: example.name,
Oops, something went wrong.

0 comments on commit 51dd462

Please sign in to comment.