shithub: hugo

Download patch

ref: f46053034759c4f9790a79e0a146dbc1b426b1ff
parent: 4c2a0de412a850745ad32e580fcd65575192ca53
author: Bjørn Erik Pedersen <[email protected]>
date: Fri Feb 21 04:02:07 EST 2020

Fix panic on no output formats

A page needs its output formats even if it should not be rendered or its resources should not be published.

Fixes #6924

--- a/hugolib/content_map_page.go
+++ b/hugolib/content_map_page.go
@@ -177,42 +177,40 @@
 
 		outputFormatsForPage := ps.m.outputFormats()
 
-		if !ps.m.noRender() {
-			// Prepare output formats for all sites.
-			ps.pageOutputs = make([]*pageOutput, len(ps.s.h.renderFormats))
-			created := make(map[string]*pageOutput)
+		// Prepare output formats for all sites.
+		// We do this even if this page does not get rendered on
+		// its own. It may be referenced via .Site.GetPage and
+		// it will then need an output format.
+		ps.pageOutputs = make([]*pageOutput, len(ps.s.h.renderFormats))
+		created := make(map[string]*pageOutput)
+		shouldRenderPage := !ps.m.noRender()
 
-			for i, f := range ps.s.h.renderFormats {
-				if po, found := created[f.Name]; found {
-					ps.pageOutputs[i] = po
-					continue
-				}
+		for i, f := range ps.s.h.renderFormats {
+			if po, found := created[f.Name]; found {
+				ps.pageOutputs[i] = po
+				continue
+			}
 
-				_, render := outputFormatsForPage.GetByName(f.Name)
-				po := newPageOutput(ps, pp, f, render)
+			render := shouldRenderPage
+			if render {
+				_, render = outputFormatsForPage.GetByName(f.Name)
+			}
 
-				// Create a content provider for the first,
-				// we may be able to reuse it.
-				if i == 0 {
-					contentProvider, err := newPageContentOutput(ps, po)
-					if err != nil {
-						return nil, err
-					}
-					po.initContentProvider(contentProvider)
-				}
+			po := newPageOutput(ps, pp, f, render)
 
-				ps.pageOutputs[i] = po
-				created[f.Name] = po
+			// Create a content provider for the first,
+			// we may be able to reuse it.
+			if i == 0 {
+				contentProvider, err := newPageContentOutput(ps, po)
+				if err != nil {
+					return nil, err
+				}
+				po.initContentProvider(contentProvider)
 			}
-		} else if ps.m.buildConfig.PublishResources {
-			// We need one output format for potential resources to publish.
-			po := newPageOutput(ps, pp, outputFormatsForPage[0], false)
-			contentProvider, err := newPageContentOutput(ps, po)
-			if err != nil {
-				return nil, err
-			}
-			po.initContentProvider(contentProvider)
-			ps.pageOutputs = []*pageOutput{po}
+
+			ps.pageOutputs[i] = po
+			created[f.Name] = po
+
 		}
 
 		if err := ps.initCommonProviders(pp); err != nil {
--- a/hugolib/disableKinds_test.go
+++ b/hugolib/disableKinds_test.go
@@ -311,3 +311,37 @@
 	b.Assert(b.CheckExists("public/section/bundle-false/data2.json"), qt.Equals, false)
 	b.AssertFileContent("public/section/bundle-true/data3.json", `Some data 3`)
 }
+
+func TestNoRenderAndNoPublishResources(t *testing.T) {
+	noRenderPage := `
+---
+title: %s
+_build:
+    render: false
+    publishResources: false
+---
+`
+	b := newTestSitesBuilder(t)
+	b.WithTemplatesAdded("index.html", `
+{{ $page := site.GetPage "sect/no-render" }}
+{{ $sect := site.GetPage "sect-no-render" }}
+
+Page: {{ $page.Title }}|RelPermalink: {{ $page.RelPermalink }}|Outputs: {{ len $page.OutputFormats }}
+Section: {{ $sect.Title }}|RelPermalink: {{ $sect.RelPermalink }}|Outputs: {{ len $sect.OutputFormats }}
+
+
+`)
+	b.WithContent("sect-no-render/_index.md", fmt.Sprintf(noRenderPage, "MySection"))
+	b.WithContent("sect/no-render.md", fmt.Sprintf(noRenderPage, "MyPage"))
+
+	b.Build(BuildCfg{})
+
+	b.AssertFileContent("public/index.html", `
+Page: MyPage|RelPermalink: |Outputs: 0
+Section: MySection|RelPermalink: |Outputs: 0
+`)
+
+	b.Assert(b.CheckExists("public/sect/no-render/index.html"), qt.Equals, false)
+	b.Assert(b.CheckExists("public/sect-no-render/index.html"), qt.Equals, false)
+
+}
--- a/hugolib/page.go
+++ b/hugolib/page.go
@@ -723,6 +723,7 @@
 			if err := meta.setMetadata(bucket, p, m); err != nil {
 				return err
 			}
+
 			frontMatterSet = true
 
 			next := iter.Peek()
--- a/hugolib/page__new.go
+++ b/hugolib/page__new.go
@@ -137,26 +137,30 @@
 			return newPageOutput(ps, pp, f, render)
 		}
 
+		shouldRenderPage := !ps.m.noRender()
+
 		if ps.m.standalone {
-			ps.pageOutput = makeOut(ps.m.outputFormats()[0], !ps.m.noRender())
+			ps.pageOutput = makeOut(ps.m.outputFormats()[0], shouldRenderPage)
 		} else {
 			outputFormatsForPage := ps.m.outputFormats()
 
-			if !ps.m.noRender() {
-				ps.pageOutputs = make([]*pageOutput, len(ps.s.h.renderFormats))
-				created := make(map[string]*pageOutput)
-				for i, f := range ps.s.h.renderFormats {
-					po, found := created[f.Name]
-					if !found {
-						_, shouldRender := outputFormatsForPage.GetByName(f.Name)
-						po = makeOut(f, shouldRender)
-						created[f.Name] = po
+			// Prepare output formats for all sites.
+			// We do this even if this page does not get rendered on
+			// its own. It may be referenced via .Site.GetPage and
+			// it will then need an output format.
+			ps.pageOutputs = make([]*pageOutput, len(ps.s.h.renderFormats))
+			created := make(map[string]*pageOutput)
+			for i, f := range ps.s.h.renderFormats {
+				po, found := created[f.Name]
+				if !found {
+					render := shouldRenderPage
+					if render {
+						_, render = outputFormatsForPage.GetByName(f.Name)
 					}
-					ps.pageOutputs[i] = po
+					po = makeOut(f, render)
+					created[f.Name] = po
 				}
-			} else {
-				// We need one output format for potential resources to publish.
-				ps.pageOutputs = []*pageOutput{makeOut(outputFormatsForPage[0], false)}
+				ps.pageOutputs[i] = po
 			}
 		}
 
--- a/resources/page/pagemeta/pagemeta.go
+++ b/resources/page/pagemeta/pagemeta.go
@@ -39,7 +39,7 @@
 	List bool
 
 	// Whether to render it.
-	Render bool
+	 Render bool
 
 	// Whether to publish its resources. These will still be published on demand,
 	// but enabling this can be useful if the originals (e.g. images) are