Fix panic on no output formats
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 21 Feb 2020 08:02:07 +0000 (09:02 +0100)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Fri, 21 Feb 2020 08:41:39 +0000 (09:41 +0100)
A page needs its output formats even if it should not be rendered or its resources should not be published.

Fixes #6924

hugolib/content_map_page.go
hugolib/disableKinds_test.go
hugolib/page.go
hugolib/page__new.go
resources/page/pagemeta/pagemeta.go

index ca84ee873ed14c7467fbd2bae3f3fb45fb50f761..18b2ee1a775c7c168f12389896a6d0032824f8a9 100644 (file)
@@ -177,42 +177,40 @@ func (m *pageMap) newPageFromContentNode(n *contentNode, parentBucket *pagesMapB
 
                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)
-
-                       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)
-
-                               // 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)
-                               }
-
+               // 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
-                               created[f.Name] = po
+                               continue
                        }
-               } 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
+
+                       render := shouldRenderPage
+                       if render {
+                               _, render = outputFormatsForPage.GetByName(f.Name)
                        }
-                       po.initContentProvider(contentProvider)
-                       ps.pageOutputs = []*pageOutput{po}
+
+                       po := newPageOutput(ps, pp, f, render)
+
+                       // 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)
+                       }
+
+                       ps.pageOutputs[i] = po
+                       created[f.Name] = po
+
                }
 
                if err := ps.initCommonProviders(pp); err != nil {
index 3d78e29f32b9e6cdb187af70aa4929ab2ec4bb79..b1c00b48efde4b0329f3f1faa508a7746162da03 100644 (file)
@@ -311,3 +311,37 @@ _build:
        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)
+
+}
index e032f5adccb08ea9f252bc171c3cc8d33719fb8d..9db8252560622c1dc733f8bd2f1a8bc17d8daf64 100644 (file)
@@ -723,6 +723,7 @@ Loop:
                        if err := meta.setMetadata(bucket, p, m); err != nil {
                                return err
                        }
+
                        frontMatterSet = true
 
                        next := iter.Peek()
index 12aeadd35ebf2325e28b5c85eb5b6325c67d98f3..4f8abdde5f53d0855fb709212a26e54806dc70bb 100644 (file)
@@ -137,26 +137,30 @@ func newPageFromMeta(
                        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
                        }
                }
 
index 1f8afdc1851de5cc877ed66fa029d504227cb8ea..033e48252b4d866ff115a613e3c1447518fbdf6a 100644 (file)
@@ -39,7 +39,7 @@ type BuildConfig struct {
        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