Default language hierarchy
awy opened this issue · comments
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")
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.
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
}