From 5a0819b9b5eb9e79826cfa0a65f235d9821b1ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Tue, 23 Jan 2018 10:02:44 +0100 Subject: [PATCH] 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 --- resource/resource.go | 48 ++++++++++++++++++--------------------- resource/resource_test.go | 15 ++++++++++++ 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/resource/resource.go b/resource/resource.go index b785cb2be..e31cb7ff7 100644 --- a/resource/resource.go +++ b/resource/resource.go @@ -56,7 +56,7 @@ type Cloner interface { 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 @@ func (l *genericResource) setName(name string) { 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 @@ func AssignMetadata(metadata []map[string]interface{}, resources ...Resource) er } 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 @@ func AssignMetadata(metadata []map[string]interface{}, resources ...Resource) er } } - 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) } } } diff --git a/resource/resource_test.go b/resource/resource_test.go index b4cf3ebed..54d200c1c 100644 --- a/resource/resource_test.go +++ b/resource/resource_test.go @@ -234,6 +234,7 @@ func TestAssignMetadata(t *testing.T) { "src": "*loGo*", "params": map[string]interface{}{ "Param1": true, + "icon": "logo", }, }, map[string]interface{}{ @@ -241,6 +242,7 @@ func TestAssignMetadata(t *testing.T) { "src": "*", "params": map[string]interface{}{ "Param2": true, + "icon": "resource", }, }, }, func(err error) { @@ -249,9 +251,22 @@ func TestAssignMetadata(t *testing.T) { 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{}{ map[string]interface{}{