shithub: hugo

Download patch

ref: 5a0819b9b5eb9e79826cfa0a65f235d9821b1ac4
parent: 78c863305f337ed4faf3cf0a23675f28b0ae5641
author: Bjørn Erik Pedersen <[email protected]>
date: Tue Jan 23 05:02:44 EST 2018

Merge matching resources params maps

This allows setting default params values in the more general resource matchers. I also allows override with more specific values if needed.

```toml
[[resources]]
src = "documents/photo_specs.pdf"
title = "Photo Specifications"
[resources.params]
ref = 90564687
icon = "photo"
[[resources]]
src = "documents/guide.pdf"
title = "Instruction Guide"
[resources.params]
ref = 90564568
[[resources]]
src = "documents/checklist.pdf"
title = "Document Checklist"
[resources.params]
ref = 90564572
[[resources]]
src = "documents/payment.docx"
title = "Proof of Payment"
[[resources]]
src = "documents/*.pdf"
title = "PDF file"
[resources.params]
icon = "pdf"
[[resources]]
src = "documents/*.docx"
title = "Word document"
[resources.params]
icon = "word"

```

In the above `TOML` example, `photo_specs.pdf` will get the `photo` icon, the other pdf files will get the default `pdf` icon.

Note that in the example above, the order matters: It will take the first value for a given params key, title or name that it finds.

Fixes #4315

--- a/resource/resource.go
+++ b/resource/resource.go
@@ -56,7 +56,7 @@
 type metaAssigner interface {
 	setTitle(title string)
 	setName(name string)
-	setParams(params map[string]interface{})
+	updateParams(params map[string]interface{})
 }
 
 // Resource represents a linkable resource, i.e. a content page, image etc.
@@ -383,8 +383,18 @@
 	l.name = name
 }
 
-func (l *genericResource) setParams(params map[string]interface{}) {
-	l.params = params
+func (l *genericResource) updateParams(params map[string]interface{}) {
+	if l.params == nil {
+		l.params = params
+		return
+	}
+
+	// Sets the params not already set
+	for k, v := range params {
+		if _, found := l.params[k]; !found {
+			l.params[k] = v
+		}
+	}
 }
 
 // Implement the Cloner interface.
@@ -452,18 +462,13 @@
 		}
 
 		var (
-			nameSet, titleSet, paramsSet bool
-			currentCounter               = 0
-			resourceSrcKey               = strings.ToLower(r.Name())
+			nameSet, titleSet bool
+			currentCounter    = 0
+			resourceSrcKey    = strings.ToLower(r.Name())
 		)
 
 		ma := r.(metaAssigner)
 		for _, meta := range metadata {
-			if nameSet && titleSet && paramsSet {
-				// No need to look further
-				break
-			}
-
 			src, found := meta["src"]
 			if !found {
 				return fmt.Errorf("missing 'src' in metadata for resource")
@@ -504,21 +509,12 @@
 					}
 				}
 
-				if !paramsSet {
-					params, found := meta["params"]
-					if found {
-						m := cast.ToStringMap(params)
-						// Needed for case insensitive fetching of params values
-						helpers.ToLowerMap(m)
-						ma.setParams(m)
-
-						if currentCounter == 0 {
-							currentCounter = counters[srcKey] + 1
-							counters[srcKey] = currentCounter
-						}
-
-						paramsSet = true
-					}
+				params, found := meta["params"]
+				if found {
+					m := cast.ToStringMap(params)
+					// Needed for case insensitive fetching of params values
+					helpers.ToLowerMap(m)
+					ma.updateParams(m)
 				}
 			}
 		}
--- a/resource/resource_test.go
+++ b/resource/resource_test.go
@@ -234,6 +234,7 @@
 				"src":   "*loGo*",
 				"params": map[string]interface{}{
 					"Param1": true,
+					"icon":   "logo",
 				},
 			},
 			map[string]interface{}{
@@ -241,6 +242,7 @@
 				"src":   "*",
 				"params": map[string]interface{}{
 					"Param2": true,
+					"icon":   "resource",
 				},
 			},
 		}, func(err error) {
@@ -249,8 +251,21 @@
 			assert.Equal("My Resource", foo3.Title())
 			_, p1 := logo2.Params()["param1"]
 			_, p2 := foo2.Params()["param2"]
+			_, p1_2 := foo2.Params()["param1"]
+			_, p2_2 := logo2.Params()["param2"]
+
+			icon1, _ := logo2.Params()["icon"]
+			icon2, _ := foo2.Params()["icon"]
+
 			assert.True(p1)
 			assert.True(p2)
+
+			// Check merge
+			assert.True(p2_2)
+			assert.False(p1_2)
+
+			assert.Equal("logo", icon1)
+			assert.Equal("resource", icon2)
 
 		}},
 		{[]map[string]interface{}{