Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print the value of a key containing dots

Tags:

templates

go

I'm trying to print the values of a map, whose keys have a dot (.) on it.

Example map:

type TemplateData struct {
    Data map[string] int
}
tpldata := TemplateData{map[string]int {"core.value": 1}}

I've tried:

{{ $key := "core.value" }}
{{ .Data.key }}

but got:

2014/06/17 16:46:17 http: panic serving [::1]:41395: template: template.html:13: bad character U+0024 '$'

and

{{ .Data."core.value" }}

but got:

2014/06/17 16:45:07 http: panic serving [::1]:41393: template: template.html:12: bad character U+0022 '"'

Note that I'm able to successfully print the value of keys without dots.

like image 916
Sebastian Kreft Avatar asked Jun 17 '14 15:06

Sebastian Kreft


2 Answers

As @martin-ghallager said, one needs to use an external function to access those elements.

Helpfully, the standard library already provides the index function (which does exactly what Martin's dotNotation function does).

To use it just write:

{{ index .Data "core.value" }}

The index function will return a default value in case the key is not present. This works if your dictionary has homogeneous data, however it will return the wrong value when it is heterogeneous. In such a case you can explicitly set the default with:

{{ 0 | or (index .Data "core.value") }}
like image 196
Sebastian Kreft Avatar answered Nov 03 '22 00:11

Sebastian Kreft


As fabrizioM has stated, it's against the specs of the package, however there's nothing stopping you creating your own accessor to use dot notation using a function map:

package main

import (
    "fmt"
    "html/template"
    "os"
)

type TemplateData struct {
    Data map[string]int
}

var funcMap = template.FuncMap{
    "dotNotation": dotNotation,
}

func main() {
    data := TemplateData{map[string]int{"core.value": 1, "test": 100}}

    t, err := template.New("foo").Funcs(funcMap).Parse(`{{dotNotation .Data "core.value"}}`)

    if err != nil {
        fmt.Println(err)
    }

    err = t.Execute(os.Stdout, data)

    if err != nil {
        fmt.Println(err)
    }
}

func dotNotation(m map[string]int, key string) int {
    // Obviously you'll need to validate existence / nil map
    return m[key]
}

http://play.golang.org/p/-rlKFx3Ayt

like image 5
Martin Gallagher Avatar answered Nov 03 '22 00:11

Martin Gallagher