URI: 
       Add map support to scratch - hugo - [fork] hugo port for 9front
  HTML git clone git@git.drkhsh.at/hugo.git
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
   DIR README
   DIR LICENSE
       ---
   DIR commit 4bed69629e55f7292505a74e8437a5a05ddf9a22
   DIR parent 8d28686edcf19b5dd067482b72fdc1b93c99ef7f
  HTML Author: Marek Janda <nyx@nyx.cz>
       Date:   Sun,  2 Aug 2015 07:00:43 +0200
       
       Add map support to scratch
       
       Diffstat:
         M docs/content/extras/scratch.md      |      14 ++++++++++++--
         M hugolib/scratch.go                  |      36 +++++++++++++++++++++++++++++++
         M hugolib/scratch_test.go             |      18 ++++++++++++++++++
       
       3 files changed, 66 insertions(+), 2 deletions(-)
       ---
   DIR diff --git a/docs/content/extras/scratch.md b/docs/content/extras/scratch.md
       @@ -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" }}`.
   DIR diff --git a/hugolib/scratch.go b/hugolib/scratch.go
       @@ -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{})}
        }
   DIR diff --git a/hugolib/scratch_test.go b/hugolib/scratch_test.go
       @@ -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)
       +        }
       +}