Get Value with key on template/html


(Marc) #1

Hi,

I would like switch a variable in my frontend. I have a variable/struct

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

in my Frontend i get as so:

{{$mylang := GetSessionString “mylang”}} //get from session lankey example “ENen”

{{range $k, $v := .Navigation}}
{{range $kk, $vv := $v.Title}}
//select the lang key
{{end}}
{{end}}

how i can select the right key with the lang-key as string from the variable $mylang {{$vv.$mylang}} <-- this is cheese…

greetings


(Johan Dahl) #2

Do you mean something like this?

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

would output:

<h1>Activities</h1>

(Marc) #3

I use a Struct

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
}

here is the index a int

I use currently a funcmap

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

This ist not sleek and only I am determined by the struct. It would be nice to be independent of the struct…


(Johan Dahl) #4

Ok I think I understand

What you could do which is a very common way in dealing with translation in other languages is to only use some kind of symbol in all your datastructures and then you want to print it in the current language you look it up and prints that. So for you could you in the title store for example the english version. 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)
	}
}



(Marc) #5

This is good, but i have a lot of strucs

example:

image

if I use a range in my template. Simply something like that would be:

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

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

Is there no way to target the Keys somehow, from a string?

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

I’ll try to play with your example. I’ll be back!!!


(Norbert Melzer) #6

Your screenshot doesn’t look like if it were from a struct but from a JSON object. If you make it an map[string]interface{}, you should be able to use index as described on SO:


(Marc) #7

Yes is are struct! My Screenshot is from ArangoDB and should only illustrate how the data is organized.

Index key must a integer. $v.Title is a object whose keys are strings.

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

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


(Norbert Melzer) #8

index works for maps as well, and as I said, if you have your data as a map you can use index, but as you are serialising into a strict with strict fields yo can not access the fields dynamically besides using reflection.