nicksnyder / go-i18n

Translate your Go program into multiple languages.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

List fitting problem

Huang-JiaWei opened this issue · comments

hi, I found that the function recGetMessages is not properly adapted to []interface{}. For example:

test.toml
Enum = ["item a", "item b", "item c", "item d"]
// recGetMessages looks for translation messages inside "raw" parameter,
// scanning nested maps using recursion.
func recGetMessages(raw interface{}, isMapMessage, isInitialCall bool) ([]*Message, error) {
......
	case []interface{}:
		// Backward compatibility for v1 file format.
		messages = make([]*Message, 0, len(data))
		for _, data := range data {
			// recursively scan slice items
			childMessages, err := recGetMessages(data, isMessage(data), false)
			if err != nil {
				return nil, err
			}
			messages = append(messages, childMessages...)
		}
......
}

The result will be four messages with the id "Enum.". 
So I can't use lists properly for international translation. I want to be able to use it like a normal access list element

I am not sure what you are trying to do with this function here. What are you expecting to happen? Are you using v1 or v2 of the library? Can you include the full implementation of recGetMessages?

I would like to be able to translate an item of the list by something like item[n]
I'm using v2@v2.2.1.
Here is an example
toml file:

item = ["item a", "item b", "item c"]

go.mod

module i18n_demo

go 1.18

require (
	github.com/BurntSushi/toml v1.0.0
	github.com/nicksnyder/go-i18n/v2 v2.2.1
)

require golang.org/x/text v0.4.0

code:

package main

import (
	"fmt"

	"github.com/BurntSushi/toml"
	"github.com/nicksnyder/go-i18n/v2/i18n"
	"golang.org/x/text/language"
)

func main() {
	bundle := i18n.NewBundle(language.English)
	bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
	bundle.LoadMessageFile("./en.toml")

	localizer := i18n.NewLocalizer(bundle, language.English.String())
	fmt.Println(localizer.LocalizeMessage(&i18n.Message{ID: "item.1"}))  // I hope I can get "item b" this way
	fmt.Println(localizer.LocalizeMessage(&i18n.Message{ID: "item[1]"})) // Or this, or some other way it could be done
	fmt.Println(localizer.LocalizeMessage(&i18n.Message{ID: "item."}))
}

>>>  <nil>
>>>  <nil>
>>> item c <nil>

In the example I define a list and LoadMessageFile it.
Later I would like to be able to translate one of its items using i18n, but as indicated above, I can only get "item c" from "item."
By debuging in the source code I found (LoadMessageFile->ParseMessageFileBytes->ParseMessageFileBytes->recGetMessages)
recGetMessages switch []interface{}

// recGetMessages looks for translation messages inside "raw" parameter,
// scanning nested maps using recursion.
func recGetMessages(raw interface{}, isMapMessage, isInitialCall bool) ([]*Message, error) {
......
	case []interface{}:
		// Backward compatibility for v1 file format.
		messages = make([]*Message, 0, len(data))
		for _, data := range data {
			// recursively scan slice items
			childMessages, err := recGetMessages(data, isMessage(data), false)
			if err != nil {
				return nil, err
			}
			messages = append(messages, childMessages...)
		}
......
}

But in the string list case all childMessages are Message{ID: "", Other: data} elements
This results in the ID of all the elements in the item list being "item.", so eventually I can't get the correct translation of item[n]

Oh, what you are trying to do is not supported. Each message key can only have one value.

You need to create a unique key for each message that you want to translate.