shithub: hugo

Download patch

ref: 634938908ec8f393b9a05d26b4cfe19ca7abb0d0
parent: c63db7f1f6774a2d661af1d8197c6fe377e3ad25
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Tue Oct 6 07:19:31 EDT 2020

pagemeta: Make BuildConfig.Render an enum

Allowing links on pages without rendering them.

Fixes #7783

--- a/docs/content/en/content-management/build-options.md
+++ b/docs/content/en/content-management/build-options.md
@@ -20,13 +20,24 @@
 
 ```yaml
 _build:
-  render: true
+  render: always
   list: always
   publishResources: true
 ```
 
 #### render
-If true, the page will be treated as a published page, holding its dedicated output files (`index.html`, etc...) and permalink.
+If `always`, the page will be treated as a published page, holding its dedicated output files (`index.html`, etc...) and permalink.
+
+{{< new-in "0.76.0" >}} We extended this property from a boolean to an enum in Hugo 0.76.0. Valid values are:
+
+never
+: The page will not be included in any page collection.
+
+always (default)
+: The page will be rendered to disk and get a `RelPermalink` etc.
+
+link
+: The page will be not be rendered to disk, but will get a `RelPermalink`.
 
 #### list
 
--- a/hugolib/disableKinds_test.go
+++ b/hugolib/disableKinds_test.go
@@ -54,8 +54,16 @@
 _build:
   render: false
 ---
-`, "sect/no-publishresources/index.md", `
+`,
+			"sect/no-render-link.md", `
 ---
+title: No Render Link
+_build:
+  render: link
+---
+`,
+			"sect/no-publishresources/index.md", `
+---
 title: No Publish Resources
 _build:
   publishResources: false
@@ -297,6 +305,20 @@
 		p := getPage(b, ref)
 		b.Assert(p, qt.Not(qt.IsNil))
 		b.Assert(p.RelPermalink(), qt.Equals, "")
+		b.Assert(p.OutputFormats(), qt.HasLen, 0)
+		b.Assert(getPageInSitePages(b, ref), qt.Not(qt.IsNil))
+		sect := getPage(b, "/sect")
+		b.Assert(getPageInPagePages(sect, ref), qt.Not(qt.IsNil))
+	})
+
+	c.Run("Build config, no render link", func(c *qt.C) {
+		b := newSitesBuilder(c, disableKind)
+		b.Build(BuildCfg{})
+		ref := "/sect/no-render-link.md"
+		b.Assert(b.CheckExists("public/sect/no-render/index.html"), qt.Equals, false)
+		p := getPage(b, ref)
+		b.Assert(p, qt.Not(qt.IsNil))
+		b.Assert(p.RelPermalink(), qt.Equals, "/blog/sect/no-render-link/")
 		b.Assert(p.OutputFormats(), qt.HasLen, 0)
 		b.Assert(getPageInSitePages(b, ref), qt.Not(qt.IsNil))
 		sect := getPage(b, "/sect")
--- a/hugolib/page__meta.go
+++ b/hugolib/page__meta.go
@@ -506,7 +506,7 @@
 			pm.params[loki] = isHeadless
 			if p.File().TranslationBaseName() == "index" && isHeadless {
 				pm.buildConfig.List = pagemeta.Never
-				pm.buildConfig.Render = false
+				pm.buildConfig.Render = pagemeta.Never
 			}
 		case "outputs":
 			o := cast.ToStringSlice(v)
@@ -683,7 +683,11 @@
 }
 
 func (p *pageMeta) noRender() bool {
-	return !p.buildConfig.Render
+	return p.buildConfig.Render != pagemeta.Always
+}
+
+func (p *pageMeta) noLink() bool {
+	return p.buildConfig.Render == pagemeta.Never
 }
 
 func (p *pageMeta) applyDefaultValues(n *contentNode) error {
--- a/hugolib/page__paths.go
+++ b/hugolib/page__paths.go
@@ -51,9 +51,11 @@
 
 		var relPermalink, permalink string
 
-		// If a page is headless or marked as "no render", or bundled in another,
+		// If a page is headless or bundled in another,
 		// it will not get published on its own and it will have no links.
-		if !pm.noRender() && !pm.bundled {
+		// We also check the build options if it's set to not render or have
+		// a link.
+		if !pm.noLink() && !pm.bundled {
 			relPermalink = paths.RelPermalink(s.PathSpec)
 			permalink = paths.PermalinkForOutputFormat(s.PathSpec, f)
 		}
--- a/resources/page/pagemeta/pagemeta.go
+++ b/resources/page/pagemeta/pagemeta.go
@@ -28,11 +28,12 @@
 	Never       = "never"
 	Always      = "always"
 	ListLocally = "local"
+	Link        = "link"
 )
 
 var defaultBuildConfig = BuildConfig{
 	List:             Always,
-	Render:           true,
+	Render:           Always,
 	PublishResources: true,
 	set:              true,
 }
@@ -49,7 +50,10 @@
 	List string
 
 	// Whether to render it.
-	Render bool
+	// Valid values: never, always, link.
+	// The value link means it will not be rendered, but it will get a RelPermalink/Permalink.
+	// Note that before 0.76.0 this was a bool, so we accept those too.
+	Render string
 
 	// 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
@@ -62,7 +66,7 @@
 // Disable sets all options to their off value.
 func (b *BuildConfig) Disable() {
 	b.List = Never
-	b.Render = false
+	b.Render = Never
 	b.PublishResources = false
 	b.set = true
 }
@@ -89,6 +93,17 @@
 	case Always, Never, ListLocally:
 	default:
 		b.List = Always
+	}
+
+	// In 0.76.0 we changed the Render from bool to a string.
+	switch b.Render {
+	case "0":
+		b.Render = Never
+	case "1":
+		b.Render = Always
+	case Always, Never, Link:
+	default:
+		b.Render = Always
 	}
 
 	return b, err
--- a/resources/page/pagemeta/pagemeta_test.go
+++ b/resources/page/pagemeta/pagemeta_test.go
@@ -31,21 +31,54 @@
 
 	configTempl := `
 [_build]
-render = true
+render = %s
 list = %s
 publishResources = true`
 
 	for _, test := range []struct {
-		list   interface{}
-		expect string
+		args   []interface{}
+		expect BuildConfig
 	}{
-		{"true", Always},
-		{"false", Never},
-		{`"always"`, Always},
-		{`"local"`, ListLocally},
-		{`"asdfadf"`, Always},
+		{
+			[]interface{}{"true", "true"},
+			BuildConfig{
+				Render:           Always,
+				List:             Always,
+				PublishResources: true,
+				set:              true,
+			}},
+		{[]interface{}{"true", "false"}, BuildConfig{
+			Render:           Always,
+			List:             Never,
+			PublishResources: true,
+			set:              true,
+		}},
+		{[]interface{}{`"always"`, `"always"`}, BuildConfig{
+			Render:           Always,
+			List:             Always,
+			PublishResources: true,
+			set:              true,
+		}},
+		{[]interface{}{`"never"`, `"never"`}, BuildConfig{
+			Render:           Never,
+			List:             Never,
+			PublishResources: true,
+			set:              true,
+		}},
+		{[]interface{}{`"link"`, `"local"`}, BuildConfig{
+			Render:           Link,
+			List:             ListLocally,
+			PublishResources: true,
+			set:              true,
+		}},
+		{[]interface{}{`"always"`, `"asdfadf"`}, BuildConfig{
+			Render:           Always,
+			List:             Always,
+			PublishResources: true,
+			set:              true,
+		}},
 	} {
-		cfg, err := config.FromConfigString(fmt.Sprintf(configTempl, test.list), "toml")
+		cfg, err := config.FromConfigString(fmt.Sprintf(configTempl, test.args...), "toml")
 		c.Assert(err, qt.IsNil)
 		bcfg, err := DecodeBuildConfig(cfg.Get("_build"))
 		c.Assert(err, qt.IsNil)
@@ -52,12 +85,7 @@
 
 		eq := qt.CmpEquals(hqt.DeepAllowUnexported(BuildConfig{}))
 
-		c.Assert(bcfg, eq, BuildConfig{
-			Render:           true,
-			List:             test.expect,
-			PublishResources: true,
-			set:              true,
-		})
+		c.Assert(bcfg, eq, test.expect)
 
 	}