mirror of
https://github.com/gohugoio/hugo.git
synced 2025-01-27 00:51:32 +00:00
Add map support to scratch
This commit is contained in:
parent
8d28686edc
commit
4bed69629e
3 changed files with 66 additions and 2 deletions
|
@ -14,9 +14,13 @@ weight: 80
|
|||
`Scratch` -- a "scratchpad" for your node- or page-scoped variables. In most cases you can do well without `Scratch`, but there are some use cases that aren't solvable with Go's templates without `Scratch`'s help, due to scoping issues.
|
||||
|
||||
|
||||
`Scratch` is added to both `Node` and `Page` -- with the three methods `Set`, `Get` and `Add`. `Set` and `Add` takes a `key` and the `value` to add. Get returns the `value` for the `key` given.
|
||||
`Scratch` is added to both `Node` and `Page` -- with following methods:
|
||||
* `Set` and `Add` takes a `key` and the `value` to add.
|
||||
* `Get` returns the `value` for the `key` given.
|
||||
* `SetInMap` takes a `key`, `mapKey` and `value`
|
||||
* `GetSortedMapValues` returns array of values from `key` sorted by `mapKey`
|
||||
|
||||
`Set` can store values of any type. `Add` accepts values that support Go's `+` operator.
|
||||
`Set` and `SetInMap` can store values of any type. `Add` accepts values that support Go's `+` operator.
|
||||
|
||||
The scope of the backing data is global for the given `Node` or `Page`, and spans partial and shortcode includes.
|
||||
|
||||
|
@ -37,6 +41,12 @@ The usage is best illustrated with some samples:
|
|||
|
||||
{{ $.Scratch.Set "v1" 123 }}
|
||||
{{ $.Scratch.Get "v1" }} {{/* => 123 */}}
|
||||
|
||||
{{ $.Scratch.SetInMap "a3" "b" "XX" }}
|
||||
{{ $.Scratch.SetInMap "a3" "a" "AA" }}
|
||||
{{ $.Scratch.SetInMap "a3" "c" "CC" }}
|
||||
{{ $.Scratch.SetInMap "a3" "b" "BB" }}
|
||||
{{ $.Scratch.GetSortedMapValues "a3" }} {{/* => []interface {}{"AA", "BB", "CC"} */}}
|
||||
```
|
||||
|
||||
**Note:** The examples above uses the special `$` variable, which refers to the top-level node. This is the behavior you most likely want, and will help remove some confusion when using `Scratch` inside page range loops -- and you start inadvertently calling the wrong `Scratch`. But there may be use cases for `{{ .Scratch.Add "key" "some value" }}`.
|
||||
|
|
|
@ -15,6 +15,7 @@ package hugolib
|
|||
|
||||
import (
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// Scratch is a writable context used for stateful operations in Page/Node rendering.
|
||||
|
@ -52,6 +53,41 @@ func (c *Scratch) Get(key string) interface{} {
|
|||
return c.values[key]
|
||||
}
|
||||
|
||||
// SetInMap stores a value to a map with the given key in the Node context.
|
||||
// This map can later be retrieved with GetSortedMapValues.
|
||||
func (c *Scratch) SetInMap(key string, mapKey string, value interface{}) string {
|
||||
_, found := c.values[key]
|
||||
if !found {
|
||||
c.values[key] = make(map[string]interface{})
|
||||
}
|
||||
|
||||
c.values[key].(map[string]interface{})[mapKey] = value
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetSortedMapValues returns a sorted map previously filled with SetInMap
|
||||
func (c *Scratch) GetSortedMapValues(key string) interface{} {
|
||||
if c.values[key] == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
unsortedMap := c.values[key].(map[string]interface{})
|
||||
|
||||
var keys []string
|
||||
for mapKey, _ := range unsortedMap {
|
||||
keys = append(keys, mapKey)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
|
||||
sortedArray := make([]interface{}, len(unsortedMap))
|
||||
for i, mapKey := range keys {
|
||||
sortedArray[i] = unsortedMap[mapKey]
|
||||
}
|
||||
|
||||
return sortedArray
|
||||
}
|
||||
|
||||
func newScratch() *Scratch {
|
||||
return &Scratch{values: make(map[string]interface{})}
|
||||
}
|
||||
|
|
|
@ -47,3 +47,21 @@ func TestScratchGet(t *testing.T) {
|
|||
t.Errorf("Should not return anything, but got %v", nothing)
|
||||
}
|
||||
}
|
||||
|
||||
func TestScratchSetInMap(t *testing.T) {
|
||||
scratch := newScratch()
|
||||
scratch.SetInMap("key", "lux", "Lux")
|
||||
scratch.SetInMap("key", "abc", "Abc")
|
||||
scratch.SetInMap("key", "zyx", "Zyx")
|
||||
scratch.SetInMap("key", "abc", "Abc (updated)")
|
||||
scratch.SetInMap("key", "def", "Def")
|
||||
assert.Equal(t, []interface{}{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"}, scratch.GetSortedMapValues("key"))
|
||||
}
|
||||
|
||||
func TestScratchGetSortedMapValues(t *testing.T) {
|
||||
scratch := newScratch()
|
||||
nothing := scratch.GetSortedMapValues("nothing")
|
||||
if nothing != nil {
|
||||
t.Errorf("Should not return anything, but got %v", nothing)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue