Skip to content

Commit eaba04e

Browse files
committed
Add list support in Scratch
1 parent 435e996 commit eaba04e

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

‎docs/content/extras/scratch.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ weight: 80
2121
* `SetInMap` takes a `key`, `mapKey` and `value`
2222
* `GetSortedMapValues` returns array of values from `key` sorted by `mapKey`
2323

24-
`Set` and `SetInMap` can store values of any type. `Add` accepts values that support Go's `+` operator.
24+
`Set` and `SetInMap` can store values of any type.
25+
26+
For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the follwing adds will be appended to that list.
2527

2628
The scope of the backing data is global for the given `Node` or `Page`, and spans partial and shortcode includes.
2729

‎hugolib/scratch.go‎

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package hugolib
1515

1616
import (
1717
"github.com/spf13/hugo/helpers"
18+
"reflect"
1819
"sort"
1920
)
2021

@@ -23,16 +24,30 @@ type Scratch struct {
2324
values map[string]interface{}
2425
}
2526

26-
// Add will add (using the + operator) the addend to the existing addend (if found).
27+
// For single values, Add will add (using the + operator) the addend to the existing addend (if found).
2728
// Supports numeric values and strings.
29+
//
30+
// If the first add for a key is an array or slice, then the next value(s) will be appended.
2831
func (c *Scratch) Add(key string, newAddend interface{}) (string, error) {
2932
var newVal interface{}
3033
existingAddend, found := c.values[key]
3134
if found {
3235
var err error
33-
newVal, err = helpers.DoArithmetic(existingAddend, newAddend, '+')
34-
if err != nil {
35-
return "", err
36+
37+
addendV := reflect.ValueOf(existingAddend)
38+
39+
if addendV.Kind() == reflect.Slice || addendV.Kind() == reflect.Array {
40+
nav := reflect.ValueOf(newAddend)
41+
if nav.Kind() == reflect.Slice || nav.Kind() == reflect.Array {
42+
newVal = reflect.AppendSlice(addendV, nav).Interface()
43+
} else {
44+
newVal = reflect.Append(addendV, nav).Interface()
45+
}
46+
} else {
47+
newVal, err = helpers.DoArithmetic(existingAddend, newAddend, '+')
48+
if err != nil {
49+
return "", err
50+
}
3651
}
3752
} else {
3853
newVal = newAddend

‎hugolib/scratch_test.go‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package hugolib
1515

1616
import (
1717
"github.com/stretchr/testify/assert"
18+
"reflect"
1819
"testing"
1920
)
2021

@@ -47,6 +48,32 @@ func TestScratchAdd(t *testing.T) {
4748

4849
}
4950

51+
func TestScratchAddSlice(t *testing.T) {
52+
scratch := newScratch()
53+
54+
_, err := scratch.Add("intSlice", []int{1, 2})
55+
assert.Nil(t, err)
56+
_, err = scratch.Add("intSlice", 3)
57+
assert.Nil(t, err)
58+
59+
sl := scratch.Get("intSlice")
60+
expected := []int{1, 2, 3}
61+
62+
if !reflect.DeepEqual(expected, sl) {
63+
t.Errorf("Slice difference, go %q expected %q", sl, expected)
64+
}
65+
66+
_, err = scratch.Add("intSlice", []int{4, 5})
67+
68+
sl = scratch.Get("intSlice")
69+
expected = []int{1, 2, 3, 4, 5}
70+
71+
if !reflect.DeepEqual(expected, sl) {
72+
t.Errorf("Slice difference, go %q expected %q", sl, expected)
73+
}
74+
75+
}
76+
5077
func TestScratchSet(t *testing.T) {
5178
scratch := newScratch()
5279
scratch.Set("key", "val")

0 commit comments

Comments
 (0)