# 本地化
## [介绍](https://github.com/kataras/iris/wiki/Localization#introduction)
本地化功能提供了一种方便的方式来检索各种语言的字符串,从而使你可以轻松地在应用程序中支持多种语言。语言字符串存储在 `./locales` 目录中的文件中。在此目录中,应存在应用程序支持的每种语言的子目录:
```source-shell
│ main.go
└───locales
├───el-GR
│ home.yml
├───en-US
│ home.yml
└───zh-CN
home.yml
```
你的应用程序的默认语言是第一种注册语言。
```source-go
app := iris.New()
// 第一个参数: 全局文件路径模式 (原文: Glob filpath patern),
// 第二个可变参数: 可选的语言标签,
// 第一个是默认值/后备选项。
app.I18n.Load("./locales/*/*", "en-US", "el-GR", "zh-CN")
```
或者, 如果你过以下方式加载所有语言:
```source-go
app.I18n.Load("./locales/*/*")
```
然后使用以下命令设置默认语言:
```source-go
app.I18n.SetDefault("en-US")
```
### [加载进入式本地文件](https://github.com/kataras/iris/wiki/Localization#load-embedded-locales)
你可能需要使用go-bindata工具将语言环境嵌入到应用程序可执行文件中。
1. 安装一个 go-bindata工具,例如: `$ go get -u github.com/go-bindata/go-bindata/...`
2. 将本地文件嵌入到你的应用程序中 `$ go-bindata -o locales.go ./locales/...`
3. 使用 `LoadAssets` 方法去初始化和加载语言 ^ 由 `go-bindata` 生成的 `AssetNames` 和 `Asset` 函数。
```source-go
ap.I18n.LoadAssets(AssetNames, Asset, "en-US", "el-GR", "zh-CN")
```
## [定义翻译](https://github.com/kataras/iris/wiki/Localization#defining-translations)
每个文件应包含翻译后的文本或者模版值的键。
### [Fmt 风格](https://github.com/kataras/iris/wiki/Localization#fmt-style)
```source-yaml
hi: "Hi %s"
```
### [模板样式](https://github.com/kataras/iris/wiki/Localization#templates-style)
```source-yaml
hi: "Hi {{ .Name }}"
# 也支持如下模版方法
# hi: "Hi {{sayHi .Name}}
```
### [INI 部分](https://github.com/kataras/iris/wiki/Localization#ini-sections)
```source-ini
[cart]
checkout = ολοκλήρωση παραγγελίας - {{.Param}}
```
> YAML, TOML, JSON, INI 文件。
## [确定当前语言环境](https://github.com/kataras/iris/wiki/Localization#determining-the-current-locale)
你可以使用 `context.GetLocale` 方法去确定当前语言环境或检查语言环境是否为给定值:
```source-go
func(ctx iris.Context) {
locale := ctx.GetLocale()
// [...]
}
```
**Locale** 界面如下所示。
```source-go
// Locale 是返回一个 `Localizer.GetLocale` 方法的接口。
//它根据 "key" 或者格式提供转换。请参见 `GetMessage`。
type Locale interface {
// Index 从语言列表返回当前语言索引。
Index() int
// Tag 返回附加到此语言环境的完整语言标签,
// 它在不同的语言环境中应该是唯一的。
Tag() *language.Tag
// Language 应该返回用户在 `New` 函数上
// 提供的此 `Locale` 的确切语言代码。
//
// 与 `Tag().String()` 相同,但它是静态的。
Language() string
// GetMessage 应该返回基于给定的 "key" 返回翻译后的文本。
GetMessage(key string, args ...interface{}) string
}
```
## [检索翻译](https://github.com/kataras/iris/wiki/Localization#retrieving-translation)
使用 `context.Tr` 方法作为获取此请求的翻译文本的快捷方式。
```source-go
func(ctx iris.Context) {
text := ctx.Tr("hi", "name")
// [...]
}
```
### [INI 部分](https://github.com/kataras/iris/wiki/Localization#ini-sections-1)
INI 部分由 `"."`分隔。第二个可选值可以是 `map` 或者一个 `struct` 作为模板值, 类似于其余文件格式。
```source-go
func(ctx iris.Context) {
text := ctx.Tr("cart.checkout", iris.Map{"Param": "a value"})
// [...]
}
```
## [内部视图](https://github.com/kataras/iris/wiki/Localization#inside-views)
```source-go
func(ctx iris.Context) {
ctx.View("index.html", iris.Map{
"tr": ctx.Tr,
})
}
```
```text-html-basic
{{ call .tr "hi" "John Doe" }}
```
## [示例](https://github.com/kataras/iris/tree/master/_examples/i18n)
```source-go
package main
import (
"github.com/kataras/iris/v12"
)
func newApp() *iris.Application {
app := iris.New()
// 配置 i18n.
// 第一个参数: 全局文件路径模式 (原文: Glob filpath patern),
// 第二个可变参数: 可选的语言标记,第一个是默认/后备参数。
app.I18n.Load("./locales/*/*.ini", "en-US", "el-GR", "zh-CN")
// app.I18n.LoadAssets for go-bindata.
// 默认值:
// app.I18n.URLParameter = "lang"
// app.I18n.Subdomain = true
//
// 设置为false以禁止路径(本地)重定向,
// 参见 https://github.com/kataras/iris/issues/1369.
// app.I18n.PathRedirect = true
app.Get("/", func(ctx iris.Context) {
hi := ctx.Tr("hi", "iris")
locale := ctx.GetLocale()
ctx.Writef("From the language %s translated output: %s", locale.Language(), hi)
})
app.Get("/some-path", func(ctx iris.Context) {
ctx.Writef("%s", ctx.Tr("hi", "iris"))
})
app.Get("/other", func(ctx iris.Context) {
language := ctx.GetLocale().Language()
fromFirstFileValue := ctx.Tr("key1")
fromSecondFileValue := ctx.Tr("key2")
ctx.Writef("From the language: %s, translated output:\n%s=%s\n%s=%s",
language, "key1", fromFirstFileValue,
"key2", fromSecondFileValue)
})
// 在你的视图中使用:
view := iris.HTML("./views", ".html")
app.RegisterView(view)
app.Get("/templates", func(ctx iris.Context) {
ctx.View("index.html", iris.Map{
"tr": ctx.Tr, // word, arguments... {call .tr "hi" "iris"}}
})
// 注意,
// Iris 也会自动添加一个 "tr" 全局模板函数,
// 唯一的区别在于你在模板中调用它的方式
// 接受语言代码作为第一个参数: {{ tr "el-GR" "hi" "iris"}}
})
//
return app
}
func main() {
app := newApp()
// 转到 http://localhost:8080/el-gr/some-path
// ^ (使用路径前缀)
//
// 或者 http://el.mydomain.com8080/some-path
// ^ (按子域-使用 hosts 文件在本地测试)
//
// 或 http://localhost:8080/zh-CN/templates
// ^ (使用大写的路径前缀)
//
// 或 http://localhost:8080/some-path?lang=el-GR
// ^ (使用url参数)
//
// 或 http://localhost:8080 (默认为 en-US)
// 或 http://localhost:8080/?lang=zh-CN
//
// 转到 http://localhost:8080/other?lang=el-GR
// 或 http://localhost:8080/other (默认为 en-US)
// 或 http://localhost:8080/other?lang=en-US
//
// 或使用Cookie设置语言。
app.Run(iris.Addr(":8080"), iris.WithSitemap("http://localhost:8080"))
}
```
## [站点地图](https://github.com/kataras/iris/wiki/Localization#sitemap)
如果 `app.I18n.PathRedirect`为 true,则 [站点地图](https://github.com/kataras/iris/wiki/Sitemap) 翻译会自动通过路径前缀设置为每个路由。 或者如果 `app.I18n.Subdomain` 为 true,则 [站点地图](https://github.com/kataras/iris/wiki/Sitemap) 翻译会自动通过子域名设置为每个路由。 或如果 `app.I18n.URLParameter` 不为空,则 [站点地图](https://github.com/kataras/iris/wiki/Sitemap) 翻译会自动通过 URL 查询参数为每个路由。
了解更多信息,请访问: <https://support.google.com/webmasters/answer/189077?hl=en>
```source-shell
GET http://localhost:8080/sitemap.xml
```
```text-xml
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>http://localhost:8080/</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/"></xhtml:link>
</url>
<url>
<loc>http://localhost:8080/some-path</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/some-path"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/some-path"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/some-path"></xhtml:link>
</url>
<url>
<loc>http://localhost:8080/other</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/other"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/other"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/other"></xhtml:link>
</url>
<url>
<loc>http://localhost:8080/templates</loc>
<xhtml:link rel="alternate" hreflang="en-US" href="http://localhost:8080/templates"></xhtml:link>
<xhtml:link rel="alternate" hreflang="el-GR" href="http://localhost:8080/el-GR/templates"></xhtml:link>
<xhtml:link rel="alternate" hreflang="zh-CN" href="http://localhost:8080/zh-CN/templates"></xhtml:link>
</url>
</urlset>
```