Localization feature provide a convenient way to retrieve strings in various languages, allowing you to easily support multiple languages within your application. Language strings are stored in files within the ./locales directory. Within this directory there should be a subdirectory for each language supported by the application:
The default language for your application is the first registered language.
app := iris.New()// First parameter: Glob filpath patern,// Second variadic parameter: Optional language tags,// the first one is the default/fallback one.app.I18n.Load("./locales/*/*", "en-US", "el-GR", "zh-CN")
Or if you load all languages by filename:
app.I18n.Load("./locales/*/*")// Then set the default language using:app.I18n.SetDefault("en-US")
Load embedded locales
You may want to embed locales with the new embed directive within your application executable.
Import the embed package; if you don’t use any exported identifiers from this package, you can do a blank import with _ "embed".
Embed directives accept paths relative to the directory containing the Go source file. We can embed multiple files or even folders with wildcards. This uses a variable of the embed.FS type, which implements a simple virtual file system.
Instead of the Load method, we should use the LoadFS one.
Defining Translations
Locale files can be written at YAML(recommended), JSON, TOML or INI form.
Each file should contain keys. Keys can have sub-keys(we call them "sections") too.
Each key's value should be of form string or map containing by its translated text (or template) or/and its pluralized key-values.
Iris i18n module supports pluralization out-of-the-box, see below.
Fmt Style
Template
Pluralization
Iris i18n supports plural variables. To define a per-locale variable you must define a new section of Vars key.
The acceptable keys for variables are:
one
"=x" where x is a number
"<x"
other
format
Example:
Then, each message can use this variable, here's how:
You can select what message will be shown based on a given plural count.
Except variables, each message can also have its plural form too!
Acceptable keys:
zero
one
two
"=x"
"<x"
">x"
other
Let's create a simple plural-featured message, it can use the Minutes variable we created above too.
Let's continue with a bit more advanced example, using template text + functions + plural + variables.
Sections
If the key is not a reserved one (e.g. one, two...) then it acts as a sub section. The sections are separated by dot characters (.).
Determining The Current Locale
You may use the context.GetLocale method to determine the current locale or check if the locale is a given value:
The Locale interface looks like this.
Retrieving Translation
Use of context.Tr method as a shortcut to get a translated text for this request.
//go:embed embedded/locales/*
var embeddedFS embed.FS
err := app.I18n.LoadFS(embeddedFS, "./embedded/locales/*/*.ini", "en-US", "el-GR")
// OR to load all languages by filename:
// app.I18n.LoadFS(embeddedFS, "./embedded/locales/*/*.ini")
// Then set the default language using:
// app.I18n.SetDefault("en-US")
hi: "Hi %s!"
ctx.Tr("Hi", "John")
// Outputs: Hi John!
hi: "Hi {{.Name}}!"
ctx.Tr("Hi", iris.Map{"Name": "John"})
// Outputs: Hi John!
# Using variables in raw string
YouLate: "You are %[1]d ${Minutes} late."
# [x] is the argument position,
# variables always have priority other fmt-style arguments,
# that's why we see [1] for houses and [2] for the string argument.
HouseCount: "%[2]s has %[1]d ${Houses}."
ctx.Tr("YouLate", 1)
// Outputs: You are 1 minute late.
ctx.Tr("YouLate", 10)
// Outputs: You are 10 minutes late.
ctx.Tr("HouseCount", 2, "John")
// Outputs: John has 2 houses.
FreeDay:
"=3": "You have three days and %[2]d ${Minutes} off." # "FreeDay" 3, 15
one: "You have a day off." # "FreeDay", 1
other: "You have %[1]d free days." # "FreeDay", 5
ctx.Tr("FreeDay", 3, 15)
// Outputs: You have three days and 15 minutes off.
ctx.Tr("FreeDay", 1)
// Outputs: You have a day off.
ctx.Tr("FreeDay", 5)
// Outputs: You have 5 free days.
Vars:
- Houses:
one: "house"
other: "houses"
- Gender:
"=1": "She"
"=2": "He"
VarTemplatePlural:
one: "${Gender} is awesome!"
other: "other (${Gender}) has %[3]d ${Houses}."
"=5": "{{call .InlineJoin .Names}} are awesome."
const (
female = iota + 1
male
)
ctx.Tr("VarTemplatePlural", iris.Map{
"PluralCount": 5,
"Names": []string{"John", "Peter"},
"InlineJoin": func(arr []string) string {
return strings.Join(arr, ", ")
},
})
// Outputs: John, Peter are awesome
ctx.Tr("VarTemplatePlural", 1, female)
// Outputs: She is awesome!
ctx.Tr("VarTemplatePlural", 2, female, 5)
// Outputs: other (She) has 5 houses.
Welcome:
Message: "Welcome {{.Name}}"
ctx.Tr("Welcome.Message", iris.Map{"Name": "John"})
// Outputs: Welcome John
// Locale is the interface which returns from a `Localizer.GetLocale` metod.
// It serves the transltions based on "key" or format. See `GetMessage`.
type Locale interface {
// Index returns the current locale index from the languages list.
Index() int
// Tag returns the full language Tag attached tothis Locale,
// it should be uniue across different Locales.
Tag() *language.Tag
// Language should return the exact languagecode of this `Locale`
//that the user provided on `New` function.
//
// Same as `Tag().String()` but it's static.
Language() string
// GetMessage should return translated text based n the given "key".
GetMessage(key string, args ...interface{}) string
}
func(ctx iris.Context) {
text := ctx.Tr("hi", "name")
// [...]
}