• Stars
    star
    108
  • Rank 321,259 (Top 7 %)
  • Language
    Go
  • License
    MIT License
  • Created almost 5 years ago
  • Updated about 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

๐Ÿ†• High-performant and powerful localization and internationalization support for Go

i18n (Go)

build status report card godocs donate on Stripe

Efficient and easy to use localization and internationalization support for Go.

Installation

The only requirement is the Go Programming Language.

$ go get github.com/kataras/i18n@latest

Examples

Getting started

Create a folder named ./locales and put some YAML, TOML, JSON or INI files.

โ”‚   main.go
โ””โ”€โ”€โ”€locales
    โ”œโ”€โ”€โ”€el-GR
    โ”‚       example.yml
    โ”œโ”€โ”€โ”€en-US
    โ”‚       example.yml
    โ””โ”€โ”€โ”€zh-CN
            example.yml

Now, put the key-values content for each locale, e.g. ./locales/en-US/example.yml

hi: "Hi %s"
#
# Templates are supported
# hi: "Hi {{ .Name }}
#
# Template functions are supported
# hi: "Hi {{sayHi .Name}}
# ./locales/el-GR/example.yaml
hi: "ฮ“ฮตฮนฮฌ ฯƒฮฟฯ… %s"
# ./locales/zh-CN/example.yaml
hi: ๆ‚จๅฅฝ %s

Some other possible filename formats...

  • page.en.yaml
  • home.cart.el-GR.json
  • /el/file.tml

The language code MUST be right before the file extension.

The Default I18n instance will try to load locale files from ./locales directory. Use the Tr package-level function to translate a text based on the given language code. Use the GetMessage function to translate a text based on the incoming http.Request. Use the Router function to wrap an http.Handler (i.e an http.ServeMux) to set the language based on path prefix such as /zh-CN/some-path and subdomains such as zh.domain.com without the requirement of different routes per language.

Let's take a look at the simplest usage of this package.

package main

import (
	"fmt"

	"github.com/kataras/i18n"
)

type user struct {
	Name string
	Age  int
}

func main() {
	// i18n.SetDefaultLanguage("en-US")

	// Fmt style.
	enText := i18n.Tr("en", "hi", "John Doe") // or "en-US"
	elText := i18n.Tr("el", "hi", "John Doe")
	zhText := i18n.Tr("zh", "hi", "John Doe")

	fmt.Println(enText)
	fmt.Println(elText)
	fmt.Println(zhText)

	// Templates style.
	templateData := user{
		Name: "John Doe",
		Age:  66,
	}

	enText = i18n.Tr("en-US", "intro", templateData) // or "en"
	elText = i18n.Tr("el-GR", "intro", templateData)
	zhText = i18n.Tr("zh-CN", "intro", templateData)

	fmt.Println(enText)
	fmt.Println(elText)
	fmt.Println(zhText)
}

Load specific languages over a new I18n instance. The default language is the first registered, in that case is the "en-US".

I18n, err := i18n.New(i18n.Glob("./locales/*/*"), "en-US", "el-GR", "zh-CN")

Load embedded files through a go-bindata package:

I18n, err := i18n.New(i18n.Assets(AssetNames, Asset), "en-US", "el-GR", "zh-CN")

Load embedded files through Go's embed directive (recommended):

//go:embed static/locales/*
var staticFS embed.FS

loader, err := i18n.FS(staticFS, "./static/locales/*/*.yml")
// [handle error...]
I18n, err := i18n.New(loader, "en-US", "el-GR", "zh-CN")

Load through a simple Go map:

m := i18n.LangMap{
    "en-US": i18n.Map{
        "buy":               `buy %d`,
        "cart.checkout":     `checkout - {{.Param}}`,
        "cart.after.thanks": `thanks`,
        //
        "JSONTemplateExample":  `value of {{.Value}}`,
        "TypeOf":               `type of %T`,
        "KeyOnlyOnDefaultLang": `value`,
        //
        "title": `Title`,
        "hi":    `Hi {{.Name}}`,
        "int":   `1`,
        "hello": `Hello %s`,
        //
        "welcome": `welcome`,
    },
    "el-GR": i18n.Map{
        "buy":               `ฮฑฮณฮฟฯฮฌฯƒฯ„ฮต %d`,
        "cart.checkout":     `ฮฟฮปฮฟฮบฮปฮฎฯฯ‰ฯƒฮท ฯ€ฮฑฯฮฑฮณฮณฮตฮปฮฏฮฑฯ‚ - {{.Param}}`,
        "cart.after.thanks": `ฮตฯ…ฯ‡ฮฑฯฮนฯƒฯ„ฮฟฯฮผฮต`,
        //
        "JSONTemplateExample": `ฯ„ฮนฮผฮฎ ฯ„ฮฟฯ… {{.Value}}`,
        "TypeOf":              `ฯ„ฯฯ€ฮฟฯ‚ %T`,
        //
        "title": `ฮคฮฏฯ„ฮปฮฟฯ‚`,
        "hi":    `ฮ“ฮตฮนฮฌ ฯƒฮฟฯ… {{.Name}}`,
        "int":   `1`,
        //
        "welcome": `ฮบฮฑฮปฯŽฯ‚ ฮฎฯฮธฮฑฯ„ฮต`,
    },
}

loader := i18n.KV(m)

i18N, err := i18n.New(loader, "en-US", "el-GR")

Template variables & functions

Using template variables & functions as values in your locale value entry via LoaderConfig.

We are going to use a 3rd-party package for plural and singular words. Note that this is only for english dictionary, but you can use the "current" Locale and make a map with dictionaries to pluralize words based on the given language.

Before we get started, install the necessary packages:

$ go get github.com/kataras/i18n@master
$ go get github.com/gertd/go-pluralize@master

Let's create two simple translation files for our example. The ./locales/en-US/welcome.yml and ./locales/el-GR/welcome.yml respectfully:

Dog: "dog"
HiDogs: Hi {{plural (tr "Dog") .count }}
Dog: "ฯƒฮบฯ…ฮปฮฏ"
HiDogs: ฮ“ฮตฮนฮฌ {{plural (tr "Dog") .count }}

The tr template function is a builtin function registered per locale. It returns the key's translated value. E.g. on english file the tr "Dog" returns the Dog:'s value: "dog" and on greek file it returns "ฯƒฮบฯ…ฮปฮฏ". This function helps importing a key to another key to complete a sentence.

Now, create a main.go file and store the following contents:

package main

import (
    "fmt"
    "text/template"

    "github.com/kataras/i18n"
    "github.com/gertd/go-pluralize"
)

var pluralizeClient = pluralize.NewClient()

func getFuncs(current *i18n.Locale) template.FuncMap {
    return template.FuncMap{
        "plural": func(word string, count int) string {
            return pluralizeClient.Pluralize(word, count, true)
        },
    }
}

func main() {
    I18n, err := i18n.New(i18n.Glob("./locales/*/*", i18n.LoaderConfig{
        // Set custom functions per locale!
        Funcs: getFuncs,
    }), "en-US", "el-GR", "zh-CN")
    if err != nil {
        panic(err)
    }

    textEnglish := I18n.Tr("en", "HiDogs", map[string]interface{}{
        "count": 2,
    }) // prints "Hi 2 dogs".
    fmt.Println(textEnglish)

    textEnglishSingular := I18n.Tr("en", "HiDogs", map[string]interface{}{
        "count": 1,
    }) // prints "Hi 1 dog".
    fmt.Println(textEnglishSingular)

    textGreek := I18n.Tr("el", "HiDogs", map[string]interface{}{
        "count": 1,
    }) // prints "ฮ“ฮตฮนฮฌ 1 ฯƒฮบฯ…ฮปฮฏ".
    fmt.Println(textGreek)
}

Use go run main.go to run our small Go program. The output should look like this:

Hi 2 dogs
Hi 1 dog
ฮ“ฮตฮนฮฌ 1 ฯƒฮบฯ…ฮปฮฏ

HTTP

HTTP, automatically searches for url parameter, cookie, custom function and headers for the current user language.

mux := http.NewServeMux()

I18n.URLParameter = "lang" // i.e https://domain.com?lang=el
I18n.Cookie = "lang"
I18n.ExtractFunc = func(r *http.Request) string { /* custom logic */ }

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    translated := I18n.GetMessage(r, "hi", "John Doe")
    fmt.Fprintf(w, "Text: %s", translated)
})

Prefer GetLocale if more than one GetMessage call.

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    locale := I18n.GetLocale(r)
    translated := locale.GetMessage("hi", "John Doe")
    // [...some locale.GetMessage calls]
})

Optionally, identify the current language by subdomain or path prefix, e.g. en.domain.com and domain.com/en or domain.com/en-US and e.t.c.

I18n.Subdomain = true

http.ListenAndServe(":8080", I18n.Router(mux))

If the ContextKey field is not empty then the Router will set the current language.

I18n.ContextKey = "lang" 

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    currentLang := r.Context().Value("lang").(string)
    fmt.Fprintf(w, "Language: %s", currentLang)
})

Set the translate function as a key on a HTML Template.

templates, _ := template.ParseGlob("./templates/*.html")

mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    // per-request.
    translateFunc := I18n.GetLocale(r).GetMessage

    templates.ExecuteTemplate(w, "index.html", map[string]interface{}{
        "tr": translateFunc,
    })

    // {{ call .tr "hi" "John Doe" }}
})

Global function with the language as its first input argument.

translateLangFunc := I18n.Tr
templates.Funcs(template.FuncMap{
    "tr": translateLangFunc,
})

// {{ tr "en" "hi" "John Doe" }}

For a more detailed technical documentation you can head over to our godocs. And for executable code you can always visit the _examples repository's subdirectory.

License

kataras/i18n is free and open-source software licensed under the MIT License.

More Repositories

1

iris

The fastest HTTP/2 Go Web Framework. New, modern and easy to learn. Fast development with Code you control. Unbeatable cost-performance ratio ๐Ÿš€
Go
24,911
star
2

neffos

A modern, fast and scalable websocket framework with elegant API written in Go
Go
563
star
3

golog

A high-performant Logging Foundation for Go Applications. X3 faster than the rest leveled loggers.
Go
321
star
4

muxie

Muxie is a modern, fast and light HTTP multiplexer for Go. Fully compatible with the http.Handler interface. Written for everyone.
Go
283
star
5

go-sessions

๐Ÿ” The sessions manager for the Go Programming Language. Supports both net/http and fasthttp.
Go
207
star
6

jwt

A fast and simple JWT implementation for Go
Go
194
star
7

rizla

๐Ÿ‘€ Rizla builds, runs and monitors your Go Applications with ease. See https://github.com/kataras/iris-cli for Iris users.
Go
190
star
8

iris-cli

[WIP] Iris Command Line Interface
Go
118
star
9

go-events

๐Ÿ“ฃ Pure nodejs EventEmmiter for the Go Programming Language.
Go
96
star
10

server-benchmarks

๐Ÿš€ Cross-platform transparent benchmarks for HTTP/2 Web Servers at 2020-2024
Go
89
star
11

blocks

Go-idiomatic View Engine
Go
70
star
12

go-websocket

๐Ÿ”ˆ Deprecated. Use https://github.com/kataras/neffos instead
Go
59
star
13

go-template

๐Ÿ”ˆ Deprecated. Use https://github.com/kataras/iris/wiki/View instead
Go
56
star
14

versioning

๐Ÿ†• API Versioning for Go
Go
51
star
15

build-a-better-web-together

Deprecated. Moved to https://github.com/kataras/iris/wiki and https://docs.iris-go.com
CSS
48
star
16

httpcache

ABANDONED: Use https://github.com/kataras/iris instead. Extremely-easy cache service for HTTP/x . Supports both net/http and valyala/fasthttp
Go
43
star
17

neffos.js

Node.js and Browser support for the neffos real-time framework written in Typescript.
TypeScript
39
star
18

hcaptcha

hCaptcha HTTP middleware for Go web servers
Go
32
star
19

pg

PG is a Go library that simplifies PostgreSQL database interaction with struct-based entities, schema management, and repository pattern.
Go
28
star
20

tunnel

Public URLs for exposing your local web server
Go
26
star
21

go-fs

๐Ÿ“ Provides some common utilities which GoLang developers use when working with files, either system files or web files.
Go
26
star
22

rewrite

The rewrite middleware for Go. Perfect for SEO
Go
22
star
23

httpfs

Flexible and easy to use HTTP File Server for Go
Go
20
star
24

pio

Low-level package that provides an easy way to centralize different output targets. Supports colors and text decoration to all popular terminals
Go
20
star
25

sitemap

๐Ÿ†• Sitemap Protocol for Go | https://support.google.com/webmasters/answer/189077?hl=en
Go
19
star
26

go-errors

โš ๏ธ Better GoLang error handling.
Go
18
star
27

compress

HTTP Compression for Go
Go
16
star
28

go-serializer

โžฟ Serialize any custom type or convert any content to []byte or string, for Go Programming Language
Go
16
star
29

chronos

NEW: Chronos provides an easy way to limit X operations per Y time in accuracy of nanoseconds
Go
14
star
30

basicauth

The most advanced and powerful Go HTTP Basic Authentication middleware.
Go
13
star
31

gitbook-to-wiki

Export your GitBook as a GitHub Wiki or Docsify pages.
Go
13
star
32

sheets

๐Ÿ“Š (Unofficial) A Lightweight Google Spreadsheets Client written in Go
Go
12
star
33

vscode-iris

Iris Web Framework snippets for Visual Studio Code
TypeScript
9
star
34

realip

Extract the real HTTP client's Remote IP Address
Go
8
star
35

methodoverride

๐Ÿ†• Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it
Go
8
star
36

trie-examples-to-remember-again

A place to keep my coding examples for different kind of trie usage in order to remember them again - this time on github
Go
7
star
37

requestid

Unique Identifier for each HTTP request
Go
6
star
38

go-options

๐Ÿ“ฆ Clean APIs for your Go Applications
Go
5
star
39

httpclient

HTTP/2 Client for Go Programming Language #golang #http
Go
4
star
40

mail

Mail is a ridiculous simple email sender written in Go
Go
4
star
41

pkg

Public Repository of the common packages that Gerasimos Maropoulos, the author of Iris, uses for various commercial or non-commercial projects.
Go
4
star
42

pgx-golog

pgx and golog integration
Go
3
star
43

ultrasecurity

10 seconds post-login OS security
Go
1
star
44

kataras

Gerasimos Maropoulos
1
star