I18n provides internationalization support for your application, it supports 2 kinds of storages(backends), the database and file system.
Initialize I18n with the storage mode. You can use both storages together, the earlier one has higher priority. So in the example, I18n will look up the translation in database first, then continue finding it in the YAML file if not found.
import (
"github.com/jinzhu/gorm"
"github.com/itdept/i18n"
"github.com/itdept/i18n/backends/database"
"github.com/itdept/i18n/backends/yaml"
)
func main() {
db, _ := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
I18n := i18n.New(
database.New(&db), // load translations from the database
yaml.New(filepath.Join(config.Root, "config/locales")), // load translations from the YAML files in directory `config/locales`
)
I18n.T("en-US", "demo.greeting") // Not exist at first
I18n.T("en-US", "demo.hello") // Exists in the yml file
}Once a database has been set for I18n, all untranslated translations inside I18n.T() will be loaded into translations table in the database when compiling the application. For example, we have an untranslated I18n.T("en-US", "demo.greeting") in the example, so I18n will generate this record in the translations table after compiling.
| locale | key | value |
|---|---|---|
| en-US | demo.greeting |
The YAML file format is
en-US:
demo:
hello: "Hello, world"The easy way to use I18n in a template is to define a t function and register it as FuncMap:
func T(key string, value string, args ...interface{}) string {
return I18n.Default(value).T("en-US", key, args...)
}
// then use it in the template
{{ t "demo.greet" "Hello, {{$1}}" "John" }} // -> Hello, JohnI18n has functions to manage translation directly.
// Add Translation
I18n.AddTranslation(&i18n.Translation{Key: "hello-world", Locale: "en-US", Value: "hello world"})
// Update Translation
I18n.SaveTranslation(&i18n.Translation{Key: "hello-world", Locale: "en-US", Value: "Hello World"})
// Delete Translation
I18n.DeleteTranslation(&i18n.Translation{Key: "hello-world", Locale: "en-US", Value: "Hello World"})Call Translation with Scope or set default value.
// Read Translation with `Scope`
I18n.Scope("home-page").T("zh-CN", "hello-world") // read translation with translation key `home-page.hello-world`
// Read Translation with `Default Value`
I18n.Default("Default Value").T("zh-CN", "non-existing-key") // Will return default value `Default Value`I18n has a Fallbacks function to register fallbacks. For example, registering en-GB as a fallback to zh-CN:
i18n := New(&backend{})
i18n.AddTranslation(&Translation{Key: "hello-world", Locale: "en-GB", Value: "Hello World"})
fmt.Print(i18n.Fallbacks("en-GB").T("zh-CN", "hello-world")) // "Hello World"To set fallback Locale globally you can use I18n.FallbackLocales. This function accepts a map[string][]string as parameter. The key is the fallback Locale and the []string is the Locales that could fallback to the first Locale.
For example, setting "fr-FR", "de-DE", "zh-CN" fallback to en-GB globally:
I18n.FallbackLocales = map[string][]string{"en-GB": []{"fr-FR", "de-DE", "zh-CN"}}I18n utilizes a Golang template to parse translations with an interpolation variable.
type User struct {
Name string
}
I18n.AddTranslation(&i18n.Translation{Key: "hello", Locale: "en-US", Value: "Hello {{.Name}}"})
I18n.T("en-US", "hello", User{Name: "Jinzhu"}) //=> Hello JinzhuI18n utilizes cldr to achieve pluralization, it provides the functions p, zero, one, two, few, many, other for this purpose. Please refer to cldr documentation for more information.
I18n.AddTranslation(&i18n.Translation{Key: "count", Locale: "en-US", Value: "{{p "Count" (one "{{.Count}} item") (other "{{.Count}} items")}}"})
I18n.T("en-US", "count", map[string]int{"Count": 1}) //=> 1 itemI18n.AddTranslation(&i18n.Translation{Key: "ordered_params", Locale: "en-US", Value: "{{$1}} {{$2}} {{$1}}"})
I18n.T("en-US", "ordered_params", "string1", "string2") //=> string1 string2 string1Released under the MIT License.