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
This commit is contained in:
Bjørn Erik Pedersen 2018-01-23 10:02:44 +01:00
parent 78c863305f
commit 5a0819b9b5
2 changed files with 37 additions and 26 deletions

View file

@ -56,7 +56,7 @@ type Cloner interface {
type metaAssigner interface { type metaAssigner interface {
setTitle(title string) setTitle(title string)
setName(name 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. // 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 l.name = name
} }
func (l *genericResource) setParams(params map[string]interface{}) { func (l *genericResource) updateParams(params map[string]interface{}) {
l.params = params 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. // Implement the Cloner interface.
@ -452,18 +462,13 @@ func AssignMetadata(metadata []map[string]interface{}, resources ...Resource) er
} }
var ( var (
nameSet, titleSet, paramsSet bool nameSet, titleSet bool
currentCounter = 0 currentCounter = 0
resourceSrcKey = strings.ToLower(r.Name()) resourceSrcKey = strings.ToLower(r.Name())
) )
ma := r.(metaAssigner) ma := r.(metaAssigner)
for _, meta := range metadata { for _, meta := range metadata {
if nameSet && titleSet && paramsSet {
// No need to look further
break
}
src, found := meta["src"] src, found := meta["src"]
if !found { if !found {
return fmt.Errorf("missing 'src' in metadata for resource") 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"]
params, found := meta["params"] if found {
if found { m := cast.ToStringMap(params)
m := cast.ToStringMap(params) // Needed for case insensitive fetching of params values
// Needed for case insensitive fetching of params values helpers.ToLowerMap(m)
helpers.ToLowerMap(m) ma.updateParams(m)
ma.setParams(m)
if currentCounter == 0 {
currentCounter = counters[srcKey] + 1
counters[srcKey] = currentCounter
}
paramsSet = true
}
} }
} }
} }

View file

@ -234,6 +234,7 @@ func TestAssignMetadata(t *testing.T) {
"src": "*loGo*", "src": "*loGo*",
"params": map[string]interface{}{ "params": map[string]interface{}{
"Param1": true, "Param1": true,
"icon": "logo",
}, },
}, },
map[string]interface{}{ map[string]interface{}{
@ -241,6 +242,7 @@ func TestAssignMetadata(t *testing.T) {
"src": "*", "src": "*",
"params": map[string]interface{}{ "params": map[string]interface{}{
"Param2": true, "Param2": true,
"icon": "resource",
}, },
}, },
}, func(err error) { }, func(err error) {
@ -249,9 +251,22 @@ func TestAssignMetadata(t *testing.T) {
assert.Equal("My Resource", foo3.Title()) assert.Equal("My Resource", foo3.Title())
_, p1 := logo2.Params()["param1"] _, p1 := logo2.Params()["param1"]
_, p2 := foo2.Params()["param2"] _, 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(p1)
assert.True(p2) 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{}{
map[string]interface{}{ map[string]interface{}{