shithub: hugo

Download patch

ref: ae63c2b5c94f68fbabd5dbd821630e747e8959a4
parent: e627449c0a2f1d2ffac29357c4f1832fc5462870
author: Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
date: Wed Aug 19 05:15:14 EDT 2020

Fail on  partials with return when given none or a zero argument

We need to make a proper fix for this, but it is better with an error than just silently continue.

Fixes #7572
Updates #7528

--- a/hugolib/template_test.go
+++ b/hugolib/template_test.go
@@ -424,42 +424,79 @@
 
 func TestPartialWithReturn(t *testing.T) {
 
-	b := newTestSitesBuilder(t).WithSimpleConfigFile()
+	c := qt.New(t)
 
-	b.WithTemplatesAdded(
-		"index.html", `
-Test Partials With Return Values:
-
-add42: 50: {{ partial "add42.tpl" 8 }}
-dollarContext: 60: {{ partial "dollarContext.tpl" 18 }}
-adder: 70: {{ partial "dict.tpl" (dict "adder" 28) }}
-complex: 80: {{ partial "complex.tpl" 38 }}
-`,
-		"partials/add42.tpl", `
+	newBuilder := func(t testing.TB) *sitesBuilder {
+		b := newTestSitesBuilder(t).WithSimpleConfigFile()
+		b.WithTemplatesAdded(
+			"partials/add42.tpl", `
 		{{ $v := add . 42 }}
 		{{ return $v }}
 		`,
-		"partials/dollarContext.tpl", `
+			"partials/dollarContext.tpl", `
 {{ $v := add $ 42 }}
 {{ return $v }}
 `,
-		"partials/dict.tpl", `
+			"partials/dict.tpl", `
 {{ $v := add $.adder 42 }}
 {{ return $v }}
 `,
-		"partials/complex.tpl", `
+			"partials/complex.tpl", `
 {{ return add . 42 }}
+`, "partials/hello.tpl", `
+		{{ $v := printf "hello %s" . }}
+		{{ return $v }}
+		`,
+		)
+
+		return b
+
+	}
+
+	c.Run("Return", func(c *qt.C) {
+		b := newBuilder(c)
+
+		b.WithTemplatesAdded(
+			"index.html", `
+Test Partials With Return Values:
+
+add42: 50: {{ partial "add42.tpl" 8 }}
+hello world: {{ partial "hello.tpl" "world" }}
+dollarContext: 60: {{ partial "dollarContext.tpl" 18 }}
+adder: 70: {{ partial "dict.tpl" (dict "adder" 28) }}
+complex: 80: {{ partial "complex.tpl" 38 }}
 `,
-	)
+		)
 
-	b.CreateSites().Build(BuildCfg{})
+		b.CreateSites().Build(BuildCfg{})
 
-	b.AssertFileContent("public/index.html",
-		"add42: 50: 50",
-		"dollarContext: 60: 60",
-		"adder: 70: 70",
-		"complex: 80: 80",
-	)
+		b.AssertFileContent("public/index.html", `
+add42: 50: 50
+hello world: hello world
+dollarContext: 60: 60
+adder: 70: 70
+complex: 80: 80
+`,
+		)
+
+	})
+
+	c.Run("Zero argument", func(c *qt.C) {
+		b := newBuilder(c)
+
+		b.WithTemplatesAdded(
+			"index.html", `
+Test Partials With Return Values:
+
+add42: fail: {{ partial "add42.tpl" 0 }}
+
+`,
+		)
+
+		e := b.CreateSites().BuildE(BuildCfg{})
+		b.Assert(e, qt.Not(qt.IsNil))
+
+	})
 
 }
 
--- a/tpl/partials/partials.go
+++ b/tpl/partials/partials.go
@@ -25,6 +25,7 @@
 	"strings"
 	"sync"
 
+	"github.com/gohugoio/hugo/common/hreflect"
 	texttemplate "github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate"
 
 	"github.com/gohugoio/hugo/helpers"
@@ -93,14 +94,10 @@
 // Else, the rendered output will be returned:
 // A string if the partial is a text/template, or template.HTML when html/template.
 func (ns *Namespace) Include(name string, contextList ...interface{}) (interface{}, error) {
-	if strings.HasPrefix(name, "partials/") {
-		name = name[8:]
-	}
-	var context interface{}
+	name = strings.TrimPrefix(name, "partials/")
 
-	if len(contextList) == 0 {
-		context = nil
-	} else {
+	var context interface{}
+	if len(contextList) > 0 {
 		context = contextList[0]
 	}
 
@@ -124,6 +121,10 @@
 	var w io.Writer
 
 	if info.HasReturn {
+		if !hreflect.IsTruthful(context) {
+			// TODO(bep) we need to fix this, but it is non-trivial.
+			return nil, errors.New("partials that returns a value needs a non-zero argument.")
+		}
 		// Wrap the context sent to the template to capture the return value.
 		// Note that the template is rewritten to make sure that the dot (".")
 		// and the $ variable points to Arg.