如何打印包含点的键的值

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.

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") }}

No you can't. According to the specs in http://golang.org/pkg/text/template/#Arguments, the key must be alphanumeric

- The name of a key of the data, which must be a map, preceded
  by a period, such as
    .Key
  The result is the map element value indexed by the key.
  Key invocations may be chained and combined with fields to any
  depth:
    .Field1.Key1.Field2.Key2
  Although the key must be an alphanumeric identifier, unlike with
  field names they do not need to start with an upper case letter.
  Keys can also be evaluated on variables, including chaining:
    $x.key1.key2

You can still print it by iterating over the Map package main

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

type TemplateData struct {
    Data map[string]int
}

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

    t, err := template.New("foo").Parse(`{{range $key, $value := .Data}}
   {{$key}}: {{$value}}
{{end}}`)
    if err != nil {
        fmt.Println(err)
    }
    err = t.Execute(os.Stdout, data)
    if err != nil {
        fmt.Println(err)
    }
}

http://play.golang.org/p/6xB_7WQ-59

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

I had a similar issue where my key names in secret vault had - and . in it for example

test-key or test.key

If solved it like this

    {{ with secret "secret/path/test"}}
       {{ range $k, $v := .Data }}
          {{ $k }}:{{ $v }}
          {{ end }}
    {{ end }}

Hope this will help someone...