shithub: hugo

Download patch

ref: 306573def0e20ec16ee5c447981cc09ed8bb7ec7
parent: 80c8f3b81a9849080e64bf877288ede28d960d3f
author: Bjørn Erik Pedersen <[email protected]>
date: Thu Jul 12 07:26:51 EDT 2018

Improve type support in resources.Concat

This allows the result of `.Resources.Match` and similar to be concatenated.

Fixes #4934

--- a/hugolib/resource_chain_test.go
+++ b/hugolib/resource_chain_test.go
@@ -80,14 +80,21 @@
 {{ $a := "A" | resources.FromString "a.txt"}}
 {{ $b := "B" | resources.FromString "b.txt"}}
 {{ $c := "C" | resources.FromString "c.txt"}}
+{{ $textResources := .Resources.Match "*.txt" }}
 {{ $combined := slice $a $b $c | resources.Concat "bundle/concat.txt" }}
-T: Content: {{ $combined.Content }}|RelPermalink: {{ $combined.RelPermalink }}|Permalink: {{ $combined.Permalink }}|MediaType: {{ $combined.MediaType.Type }}
+T1: Content: {{ $combined.Content }}|RelPermalink: {{ $combined.RelPermalink }}|Permalink: {{ $combined.Permalink }}|MediaType: {{ $combined.MediaType.Type }}
+{{ with $textResources }}
+{{ $combinedText := . | resources.Concat "bundle/concattxt.txt" }}
+T2: Content: {{ $combinedText.Content }}|{{ $combinedText.RelPermalink }}
+{{ end }}
 `)
 		}, func(b *sitesBuilder) {
-			b.AssertFileContent("public/index.html", `T: Content: ABC|RelPermalink: /bundle/concat.txt|Permalink: http://example.com/bundle/concat.txt|MediaType: text/plain`)
+			b.AssertFileContent("public/index.html", `T1: Content: ABC|RelPermalink: /bundle/concat.txt|Permalink: http://example.com/bundle/concat.txt|MediaType: text/plain`)
 			b.AssertFileContent("public/bundle/concat.txt", "ABC")
-		}},
 
+			b.AssertFileContent("public/index.html", `T2: Content: t1t|t2t|`)
+			b.AssertFileContent("public/bundle/concattxt.txt", "t1t|t2t|")
+		}},
 		{"fromstring", func() bool { return true }, func(b *sitesBuilder) {
 			b.WithTemplates("home.html", `
 {{ $r := "Hugo Rocks!" | resources.FromString "rocks/hugo.txt" }}
@@ -137,12 +144,31 @@
 
 		b := newTestSitesBuilder(t).WithLogger(loggers.NewWarningLogger())
 		b.WithSimpleConfigFile()
-		b.WithContent("page.md", `
+		b.WithContent("_index.md", `
 ---
-title: Hello
+title: Home
 ---
 
-`)
+Home.
+
+`,
+			"page1.md", `
+---
+title: Hello1
+---
+
+Hello1
+`,
+			"page2.md", `
+---
+title: Hello2
+---
+
+Hello2
+`,
+			"t1.txt", "t1t|",
+			"t2.txt", "t2t|",
+		)
 
 		b.WithSourceFile(filepath.Join("assets", "css", "styles1.css"), `
 h1 {
--- a/resource/bundler/bundler.go
+++ b/resource/bundler/bundler.go
@@ -62,7 +62,7 @@
 }
 
 // Concat concatenates the list of Resource objects.
-func (c *Client) Concat(targetPath string, resources []resource.Resource) (resource.Resource, error) {
+func (c *Client) Concat(targetPath string, resources resource.Resources) (resource.Resource, error) {
 	// The CACHE_OTHER will make sure this will be re-created and published on rebuilds.
 	return c.rs.ResourceCache.GetOrCreate(resource.CACHE_OTHER, targetPath, func() (resource.Resource, error) {
 		var resolvedm media.Type
--- a/tpl/resources/resources.go
+++ b/tpl/resources/resources.go
@@ -79,19 +79,38 @@
 
 // Concat concatenates a slice of Resource objects. These resources must
 // (currently) be of the same Media Type.
-func (ns *Namespace) Concat(targetPathIn interface{}, r []interface{}) (resource.Resource, error) {
+func (ns *Namespace) Concat(targetPathIn interface{}, r interface{}) (resource.Resource, error) {
 	targetPath, err := cast.ToStringE(targetPathIn)
 	if err != nil {
 		return nil, err
 	}
-	rr := make([]resource.Resource, len(r))
-	for i := 0; i < len(r); i++ {
-		rv, ok := r[i].(resource.Resource)
-		if !ok {
-			return nil, fmt.Errorf("cannot concat type %T", rv)
+
+	var rr resource.Resources
+
+	switch v := r.(type) {
+	// This is what we get from the slice func.
+	case []interface{}:
+		rr = make([]resource.Resource, len(v))
+		for i := 0; i < len(v); i++ {
+			rv, ok := v[i].(resource.Resource)
+			if !ok {
+				return nil, fmt.Errorf("cannot concat type %T", v[i])
+			}
+			rr[i] = rv
 		}
-		rr[i] = rv
+	// This is what we get from .Resources.Match etc.
+	case resource.Resources:
+		rr = v
+	default:
+		// We may support Page collections at one point, but we need to think about ...
+		// what to acutually concatenate.
+		return nil, fmt.Errorf("slice %T not supported in concat", r)
 	}
+
+	if len(rr) == 0 {
+		return nil, errors.New("must provide one or more Resource objects to concat")
+	}
+
 	return ns.bundlerClient.Concat(targetPath, rr)
 }