英文:
How to print the value of a key containing dots
问题
我正在尝试打印一个具有点(.
)的键的映射的值。
示例映射:
type TemplateData struct {
Data map[string]int
}
tpldata := TemplateData{map[string]int{"core.value": 1}}
我尝试了以下方法:
{{ $key := "core.value" }}
{{ .Data.key }}
但是得到了以下错误:
2014/06/17 16:46:17 http: panic serving [::1]:41395: template: template.html:13: bad character U+0024 '$'
以及
{{ .Data."core.value" }}
但是得到了以下错误:
2014/06/17 16:45:07 http: panic serving [::1]:41393: template: template.html:12: bad character U+0022 '"'
请注意,我能够成功打印没有点的键的值。
英文:
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.
答案1
得分: 50
如@martin-ghallager所说,需要使用外部函数来访问这些元素。
幸运的是,标准库已经提供了index函数(它与Martin的dotNotation
函数完全相同)。
只需使用以下方式来使用它:
{{ index .Data "core.value" }}
如果键不存在,index
函数将返回一个默认值。这对于字典中具有同质数据的情况有效,但在存在异质数据时,它将返回错误的值。在这种情况下,您可以使用以下方式显式设置默认值:
{{ 0 | or (index .Data "core.value") }}
英文:
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") }}
答案2
得分: 5
如fabrizioM所述,这违反了包的规范,但是没有什么阻止你创建自己的访问器来使用点符号表示法,可以使用函数映射:
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 {
// 显然,你需要验证存在性/nil map
return m[key]
}
你可以在这里查看代码的运行结果:http://play.golang.org/p/-rlKFx3Ayt
英文:
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]
}
答案3
得分: 2
不可以。根据http://golang.org/pkg/text/template/#Arguments中的规范,键必须是字母数字组合。
- 数据的键名必须是一个映射(map)中的键,以句点开头,例如
.Key
结果将是由键索引的映射元素的值。
键调用可以与字段组合到任意深度:
.Field1.Key1.Field2.Key2
尽管键必须是字母数字标识符,但与字段名不同,它们不需要以大写字母开头。
键也可以在变量上进行求值,包括链式调用:
$x.key1.key2
您仍然可以通过遍历映射来打印它。
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
英文:
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)
}
}
答案4
得分: 0
我遇到了一个类似的问题,我的密钥名称中包含 -
和 .
,例如 test-key
或 test.key
。
我是这样解决的:
{{ with secret "secret/path/test"}}
{{ range $k, $v := .Data }}
{{ $k }}:{{ $v }}
{{ end }}
{{ end }}
希望这对某人有帮助...
英文:
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...
答案5
得分: -1
同样适用于 Vault 模板,当将密钥导出为环境变量时,以下代码对我有效:
{{- with secret "secret/path/mysecret" -}}
export MYVAR="{{ index .Data.data "mykey"}}"
{{- end }}
英文:
Similarly for vault templates when exporting secrets as envvars this worked for me:
{{- with secret "secret/path/mysecret" -}}
export MYVAR="{{ index .Data.data "mykey"}}"
{{- end }}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论