Golang中如何在template/html中通过key获取value

Golang中如何在template/html中通过key获取value 我想在前端切换一个变量。我有一个变量/结构体:

"Title": [{
    "DEde": "Tätigkeiten",
    "ENen": "Activities", 
    "FRfr": "Activités",
    "ITit": "Attività",
    "ESes": "Actividades",
    "NLnl": "Activiteiten"
  }],

在我的前端中这样获取:

{{$mylang := GetSessionString “mylang”}} // 从会话中获取语言键,例如 “ENen”

{{range $k, $v := .Navigation}} {{range $kk, $vv := $v.Title}} // 选择语言键 {{end}} {{end}}

如何使用字符串形式的语言键从变量 $mylang 中选择正确的键?{{$vv.$mylang}} <-- 这不对…

问候


更多关于Golang中如何在template/html中通过key获取value的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

index 同样适用于映射类型,正如我之前所说,如果你的数据是映射格式,就可以使用 index 方法。但当你将数据序列化为具有固定字段的结构体时,除了使用反射之外,你无法动态访问这些字段。

更多关于Golang中如何在template/html中通过key获取value的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


是的,这是结构体!我的截图来自 ArangoDB,仅用于说明数据的组织方式。

索引键必须是整数。$v.Title 是一个键为字符串的对象。

{{index $v.Title “ENen”}}

at : error calling index: can't index item of type models.NTitle

这很好,但我有很多结构体

示例:

image

如果我在模板中使用范围循环。简单来说就像这样:

{{$mylang := GetSessionString "mylang"}}

{{range $k, $v := .Navigation}}
    {{$v.Title[$mylang]}}
{{end}}

有没有办法通过字符串来定位键?

{{$v.Title["ENen"]}} // ENen 是 $mylang

我会尝试用你的示例来实验。我会回来的!!!

Moo:

这很好,但我有很多结构体

你的截图看起来不像是结构体,而像是 JSON 对象。如果你把它变成 map[string]interface{},你应该能够像 Stack Overflow 上描述的那样使用 index

Kyle Brandt

在 Go 模板中使用变量键访问映射值

go, templates, go-templates

Kyle Brandt 提问

我使用一个结构体

type Navigation struct {
	System     System
	Controller string
	Show       bool
	Roles      []string
	Title      NTitle
	Submenu    []Navipoints
}

type Navipoints struct {
	Title      NTitle
	Controller string
	Tabmenu    string
	Filter     string
	Show       bool
	Roles      []string
}

type Filter struct {
}

type NTitle struct {
	DEde string
	ENen string
	FRfr string
	ITit string
	ESes string
	NLnl string
}

这里有一个索引是整数

我目前使用一个函数映射

GetTitle: func(obj models.NTitle, key string) string {

r := reflect.ValueOf(obj)

f := reflect.Indirect(r).FieldByName(key)

return f.String()

},

{{range $k, $v := .Navigation}}
   {{GetTitle $v.Title $mylang}}
{{end}}

这不够简洁,而且我只能通过结构体来确定。如果能够独立于结构体就更好了…

你的意思是这样吗?

https://goplay.space/#JwSbjQcB3zB

package main

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

type translation map[string]string

var html = `
{{$lang := "ENen"}}

<h1>{{ index .Title $lang }}</h1>
`

func main() {
	var data = map[string]translation{"Title": translation{
		"DEde": "Tätigkeiten",
		"ENen": "Activities",
		"FRfr": "Activités",
		"ITit": "Attività",
		"ESes": "Actividades",
		"NLnl": "Activiteiten",
	},
	}

	t, err := template.New("foo").Parse(html)
	if err != nil {
		log.Fatalln(err)
	}
	err = t.ExecuteTemplate(os.Stdout, "foo", data)
	if err != nil {
		log.Fatalln(err)
	}
}

会输出:

<h1>Activities</h1>

好的,我理解了。

在处理其他语言翻译时,一个非常常见的做法是,在所有数据结构中只使用某种符号,然后当你想用当前语言打印时,就查找对应的翻译并打印出来。例如,你可以在标题中存储英文版本。https://goplay.space/#I7C-sNO0BsG

package main

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

type translationItem map[string]string

var translations = map[string]translationItem{
	"activities": translationItem{
		"DEde": "Tätigkeiten",
		"ENen": "Activities",
		"FRfr": "Activités",
	},
	"today": translationItem{
		"DEde": "Heute",
		"ENen": "Today",
		"FRfr": "Ajourdui",
	},
}

var currentLang = "DEde"

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

func translate(s string) string {
	return translations[s][currentLang]
}

var html = `
<h1>{{translate .When }}</h1>

{{ .Count }} {{translate "activities"}}
`

func main() {

	data := struct {
		When  string
		Count int
	}{
		When:  "today",
		Count: 33,
	}

	t, err := template.New("foo").Funcs(funcMap).Parse(html)
	if err != nil {
		log.Fatalln(err)
	}
	err = t.ExecuteTemplate(os.Stdout, "foo", data)
	if err != nil {
		log.Fatalln(err)
	}
}

在Go模板中,你不能直接使用变量作为嵌套键名来访问map值。你需要创建一个辅助函数来处理这种动态键名访问。

首先,在Go代码中注册一个模板函数:

func main() {
    funcMap := template.FuncMap{
        "getByKey": func(data interface{}, key string) interface{} {
            if m, ok := data.(map[string]interface{}); ok {
                return m[key]
            }
            return nil
        },
    }
    
    tmpl := template.New("").Funcs(funcMap)
    // 解析和使用模板...
}

或者如果你的数据结构是已知的,可以创建更具体的函数:

funcMap := template.FuncMap{
    "getLangValue": func(titleMap map[string]string, langKey string) string {
        if val, exists := titleMap[langKey]; exists {
            return val
        }
        return "" // 或者返回默认值
    },
}

在模板中的使用方式:

{{$mylang := GetSessionString "mylang"}}

{{range $k, $v := .Navigation}}
{{range $kk, $vv := $v.Title}}
    {{/* 使用辅助函数获取对应语言的值 */}}
    {{getByKey $vv $mylang}}
    {{/* 或者 */}}
    {{getLangValue $vv $mylang}}
{{end}}
{{end}}

如果你的数据结构是固定的,也可以直接在模板中使用索引:

{{$mylang := GetSessionString "mylang"}}

{{range $k, $v := .Navigation}}
{{range $kk, $vv := $v.Title}}
    {{if eq $mylang "DEde"}}
        {{$vv.DEde}}
    {{else if eq $mylang "ENen"}}
        {{$vv.ENen}}
    {{else if eq $mylang "FRfr"}}
        {{$vv.FRfr}}
    {{else if eq $mylang "ITit"}}
        {{$vv.ITit}}
    {{else if eq $mylang "ESes"}}
        {{$vv.ESes}}
    {{else if eq $mylang "NLnl"}}
        {{$vv.NLnl}}
    {{end}}
{{end}}
{{end}}

推荐使用第一种方法(模板函数),因为它更简洁且易于维护。

回到顶部