i18n: add the ability to register template funcs per locale

This commit is contained in:
Gerasimos (Makis) Maropoulos 2020-09-10 06:22:53 +03:00
parent a1f7f57922
commit 59b8ddf5be
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
6 changed files with 59 additions and 27 deletions

View File

@ -650,6 +650,7 @@ New Context Methods:
Breaking Changes:
- The `i18n#LoaderConfig.FuncMap template.FuncMap` field was replaced with `Funcs func(iris.Locale) template.FuncMap` in order to give current locale access to the template functions. A new `app.I18n.Loader` was introduced too, in order to make it easier for end-developers to customize the translation key values.
- Request Logger's `Columns bool` field has been removed. Use the new [accesslog](https://github.com/kataras/iris/tree/master/_examples/logging/request-logger/accesslog/main.go) middleware instead.
- The `.Binary` method of all view engines was removed: pass the go-bindata's latest version `AssetFile()` exported function as the first argument instead of string. All examples updated.
- `ContextUploadFormFiles(destDirectory string, before ...func(*Context, *multipart.FileHeader) bool) (uploaded []*multipart.FileHeader, n int64, err error)` now returns the total files uploaded too (as its first parameter) and the "before" variadic option should return a boolean, if false then the specific file is skipped.

View File

@ -170,7 +170,8 @@
* [Client-Side](compression/client/main.go)
* [Client-Side (using Iris)](compress/client-using-iris/main.go)
* Localization and Internationalization
* [i18n](i18n/main.go)
* [i18n](i18n)
* [i18n templates and functions](i18n/i18n-template)
* Authentication, Authorization & Bot Detection
* [Basic Authentication](auth/basicauth/main.go)
* [CORS](auth/cors)

View File

@ -1,12 +1,18 @@
package main
import (
"github.com/kataras/iris/v12"
"text/template"
"github.com/kataras/iris/v12"
// go get -u github.com/gertd/go-pluralize
"github.com/gertd/go-pluralize"
)
/*
Iris I18n supports text/template inside the translation values.
Follow this tutorial to learn how to use that feature.
*/
func main() {
app := newApp()
app.Listen(":8080")
@ -16,18 +22,23 @@ func newApp() *iris.Application {
app := iris.New()
pluralize := pluralize.NewClient()
app.I18n.Loader.FuncMap = map[string]interface{}{
"plural": func(word string, count int) string {
// Your own implementation or use a 3rd-party package
// like we do here.
//
// Note that this is only for english,
// but you can accept the language code
// and use a map with dictionaries to
// pluralize words based on the given language.
return pluralize.Pluralize(word, count, true)
},
// Set custom functions per locale!
app.I18n.Loader.Funcs = func(current iris.Locale) template.FuncMap {
return template.FuncMap{
"plural": func(word string, count int) string {
// Your own implementation or use a 3rd-party package
// like we do here.
//
// Note that this is only for english,
// but you can accept the language code
// and use a map with dictionaries to
// pluralize words based on the given language.
return pluralize.Pluralize(word, count, true)
},
}
}
app.I18n.Load("./locales/*/*.yml", "en-US", "el-GR")
app.Get("/", func(ctx iris.Context) {

View File

@ -7,6 +7,10 @@ import (
"github.com/kataras/iris/v12"
)
/*
See i18n-template for a more advanced translation key-values.
*/
func newApp() *iris.Application {
app := iris.New()

View File

@ -159,6 +159,9 @@ type (
//
// An alias for the `context.N`.
N = context.N
// Locale describes the i18n locale.
// An alias for the `context.Locale`.
Locale = context.Locale
)
// Constants for input argument at `router.RouteRegisterRule`.

View File

@ -26,8 +26,8 @@ type (
LoaderConfig struct {
// Template delimeters, defaults to {{ }}.
Left, Right string
// Template functions map, defaults to nil.
FuncMap template.FuncMap
// Template functions map per locale, defaults to nil.
Funcs func(context.Locale) template.FuncMap
// If true then it will return error on invalid templates instead of moving them to simple string-line keys.
// Also it will report whether the registered languages matched the loaded ones.
// Defaults to false.
@ -43,17 +43,21 @@ type (
// Apply implements the `LoaderOption` interface.
func (c *LoaderConfig) Apply(cfg *LoaderConfig) {
for k, v := range c.FuncMap {
if cfg.FuncMap == nil {
cfg.FuncMap = make(template.FuncMap)
}
cfg.FuncMap[k] = v
if c.Left != "" {
cfg.Left = c.Left
}
cfg.Left = c.Left
cfg.Right = c.Right
cfg.Strict = c.Strict
if c.Right != "" {
cfg.Right = c.Right
}
if c.Funcs != nil {
cfg.Funcs = c.Funcs
}
if c.Strict {
cfg.Strict = true
}
}
// Glob accepts a glob pattern (see: https://golang.org/pkg/path/filepath/#Glob)
@ -160,14 +164,22 @@ func load(assetNames []string, asset func(string) ([]byte, error), options ...Lo
// we assume it's template?
// each file:line has its own template funcs so,
// just map it.
builtinFuncs := template.FuncMap{
// builtin funcs.
funcs := template.FuncMap{
"tr": locale.GetMessage,
}
if c.Funcs != nil {
// set current locale's template's funcs.
for k, v := range c.Funcs(locale) {
funcs[k] = v
}
}
if t, err := template.New(k).
Delims(c.Left, c.Right).
Funcs(builtinFuncs).
Funcs(c.FuncMap).
Funcs(funcs).
Parse(value); err == nil {
templateKeys[k] = t
continue