nicksnyder / go-i18n

Translate your Go program into multiple languages.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Default language hierarchy

awy opened this issue · comments

commented

Currently, there is a single default language which is used when there is no translation available for the desired language. I'd like to support a hierarchy of defaults, for example:

  • fr-CA => fr => en

Any suggestions on how to achieve this?

When you are calling NewLocalizer it accepts an arbitrary number of priorities, so you can append a string there that will be consulted before falling back to the default language for the bundle.

l, err := NewLocalizer(bundle, userLang, "fr-CA", "fr", "en")
commented

That does not actually cover my use-case. Consider the case where the bundle contains complete translations for "fr" and "en" (the default) but for "fr-CA" it only contains translations in the case that the Canadian French translation differs from the standard French one.

You example will fail for a MessageID that is not in the "fr-CA" messages even though it is present in the "fr" ones.

Yeah, your use case is not supported by this library. go-i18n assumes that if a language has translations, then it has all the translations. I don't know what it would take to remove that assumption, but I am currently the sole maintainer of this project and don't have any time to dedicate to making changes like this. Your options are to make a fork and try to remove this assumption, or simply copy over all translations from fr to fr-CA that are the same in both locales.

commented

Thanks, I understand. I have examined the code a bit further and also looked at how some of the underlying features from language are used and implemented. I cannot see an easy to adapt the library to my use-case but I might look again later.

In the meantime I have implement the following which is sufficient for now.

func loadMessageFile(locale string) (*i18n.MessageFile, error) {
	if files[locale] != nil {
		// already loaded it
		return files[locale], nil
	}

	var messages []*i18n.Message
	if parent, ok := defaults[locale]; ok {
		if m, err := loadMessageFile(parent); err == nil {
			messages = append(messages, m.Messages...)
		}
	}

	m, err := bundle.LoadMessageFile(locale + `.json`)
	if err == nil {
		if len(messages) > 0 {
			// Append our messages to our parent's messages
			messages = append(messages, m.Messages...)
			m.Messages = messages                  // replace
			bundle.AddMessages(m.Tag, messages...) // relies on later elements overriding earlier ones with same Message.ID
		}
		// else in normal case messages added by bundle.LoadMessageFile()

		files[locale] = m
	}
	return m, err
}