gettext

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 6, 2022 License: BSD-3-Clause Imports: 12 Imported by: 0

README

goi18n

This lib is in beta. Please report any bugs or suggestions to #i18n channel

Setup

  1. Set up extraction and package build. See this guide for more information on how to set this up.
  2. Save the generated translation package somewhere that can be accessed by your application at runtime (for example, in the repo itself or in a separate golang package).
  3. Create a new TranslatorManager. Pass the path to the locale directory within the translation package.
    import (
      i "github.com/ContextLogic/goi18n/i18n"
    )
    
    golangPackageLocaleDir := "path/to/package/locale"
    tr, err := i.NewTranslatorManager(i.TranslatorRepositoryOptions{LocaleDir: golangPackageLocaleDir})
    
    ⚠ Warning: Depending on the size of your app, the TranslatorManager can be expensive to create. For this reason, in most cases, you will want to initialize only one instance of TranslationRepository when you start your app/server and keep it available in memory.
  4. Now you can use your TranslatorManager to translate strings. See below for detailed usage instructions.

Translation Functions

This lib features the 4 common translation functions used at wish:

  1. I18n Translate a string to the given locale
    tr.I18n("zh-CN", "Learn more")
    
  2. Ci18n Translate a string with context. Use this when your string's meaning is ambiguous to the given locale.
    tr.Ci18n("zh-CN", "Meaning the state of an order", "state")
    tr.Ci18n("zh-CN", "Meaning a region, like the State of New York", "state")
    
  3. Ni18n Translate a string with a singular and plural form to the given locale.
    tr.Ni18n("zh-CN", 5, "Picked up 1 day ago", "Picked up  {%1=Number of days} days ago", 5)
    
  4. Cni18n Translate a string with context, as well as singular and plural form to the given locale.
    tr.Cni18n("zh-CN", "State as in a region, like the State of New York", 5, "Available in 1 state", "Available in  {%1=Number of States} states", 5)
    

Placeholders

This lib only supports descriptive placeholders. It is important to provide good descriptive placeholders because many other languages have complex forms, which can change depending on what is inserted into placeholders. Providing good descriptions can give the translators more context to make accurate translations.

Example:

tr.I18n("zh-CN", "PayPal payment scheduled for: {%1=user email}.", user.EmailAddress)

Legacy Support for the Usage of TranslationRepository

Note: We advise against the raw usage of the TranslationRepository, you should try to use the thread-safe wrapper TranslatorManager as mentioned above

Usage Patterns

After setup, you can use the TranslationRepository to translate strings. To help you get started, consider the following two patterns for usage.

  1. Use the singleton TranslationRepository to do the translations. In this pattern, we set the desired locale globally using SetLocale. Then translate using the i18n functions (similar to how it's done in clroot).

    tr, err := i.NewTranslatorRepository(i.TranslatorRepositoryOptions{LocaleDir: golangPackageLocaleDir})
    
    err = tr.SetLocale("zh-CN")
    
    tr.I18n("Learn more")
    tr.Ci18n("LEGAL_CONSTANTS", "Terms of Use")
    tr.Ni18n(5, "1 linked product", "{%1=number of products} linked products", 5)
    tr.Cni18n("MY CONTEXT", 1, "1 string", "{%1=number of products} strings", 1)
    
  2. Use GetTranslator to get Translator instances for the locales of your choice from the TranslationRepository, and use them to translate strings independently. This is useful in multi-threaded situations, where a global locale will not suffice.

    tr, err := i.NewTranslatorRepository(i.TranslatorRepositoryOptions{LocaleDir: golangPackageLocaleDir})
    
    zhTranslator, err := tr.GetTranslator("zh-CN")
    frTranslator, err := tr.GetTranslator("fr-FR")
    
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
      zhTranslator.I18n("Learn more")
      zhTranslator.Ci18n("LEGAL_CONSTANTS", "Terms of Use")
    }
    go func() {
      frTranslator.Ni18n(5, "1 linked product", "{%1=number of products} linked products", 5)
      frTranslator.Cni18n("MY CONTEXT", 1, "1 string", "{%1=number of products} strings", 1)
    }
    wg.Wait()
    

⚠ Warning: Translators are lazy loaded. They are only initialized when SetLocale or GetTranslator is called, NOT when the TranslationRepository is created.

Full Example

import (
  i "github.com/ContextLogic/goi18n/i18n"
)

golangPackageLocaleDir := "path/to/package/locale"
tr, err := i.TranslatorManager(i.TranslatorRepositoryOptions{LocaleDir: golangPackageLocaleDir})
err = tr.SetLocale("zh-TW")
  
tr.I18n("zh-TW", "Learn more")
tr.Ci18n("zh-TW", "LEGAL_CONSTANTS", "Terms of Use")

Documentation

Overview

Package gettext implements a basic GNU's gettext library.

Example:

import (
	"github.com/ContextLogic/goi18n"
)

func main() {
	gettext.SetLanguage("zh_CN")

	// gettext.BindLocale(gettext.New("hello", "locale"))              // from locale dir
	// gettext.BindLocale(gettext.New("hello", "locale.zip"))          // from locale zip file
	// gettext.BindLocale(gettext.New("hello", "locale.zip", zipData)) // from embedded zip data

	gettext.BindLocale(gettext.New("hello", "locale"))

	// translate source text
	fmt.Println(gettext.Gettext("Hello, world!"))
	// Output: 你好, 世界!

	// translate resource
	fmt.Println(string(gettext.Getdata("poems.txt")))
	// Output: ...
}

Translate directory struct("./examples/locale.zip"):

Root: "path" or "file.zip/zipBaseName"
 +-default                 # locale: $(LC_MESSAGES) or $(LANG) or "default"
 |  +-LC_MESSAGES            # just for `gettext.Gettext`
 |  |   +-hello.mo             # $(Root)/$(lang)/LC_MESSAGES/$(domain).mo
 |  |   +-hello.po             # $(Root)/$(lang)/LC_MESSAGES/$(domain).po
 |  |   \-hello.json           # $(Root)/$(lang)/LC_MESSAGES/$(domain).json
 |  |
 |  \-LC_RESOURCE            # just for `gettext.Getdata`
 |      +-hello                # domain map a dir in resource translate
 |         +-favicon.ico       # $(Root)/$(lang)/LC_RESOURCE/$(domain)/$(filename)
 |         \-poems.txt
 |
 \-zh_CN                   # simple chinese translate
    +-LC_MESSAGES
    |   +-hello.po             # try "$(domain).po" first
    |   +-hello.mo             # try "$(domain).mo" second
    |   \-hello.json           # try "$(domain).json" third
    |
    \-LC_RESOURCE
        +-hello
           +-favicon.ico       # $(lang)/$(domain)/favicon.ico
           \-poems.txt         # $(lang)/$(domain)/poems.txt

See:

http://en.wikipedia.org/wiki/Gettext
http://www.gnu.org/software/gettext/manual/html_node
http://www.gnu.org/software/gettext/manual/html_node/Header-Entry.html
http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
http://www.gnu.org/software/gettext/manual/html_node/MO-Files.html
http://www.poedit.net/

Please report bugs to <chaishushan{AT}gmail.com>. Thanks!

Example
gettext := gettext.New("hello", "./examples/locale").SetLanguage("zh_CN")
fmt.Println(gettext.Gettext("Hello, world!"))
Output:

你好, 世界!
Example (Bind)
gettext.BindLocale(gettext.New("hello", "./examples/locale.zip"))
gettext.SetLanguage("zh_CN")

fmt.Println(gettext.Gettext("Hello, world!"))
Output:

你好, 世界!
Example (Json)
const jsonData = `{
		"zh_CN": {
			"LC_MESSAGES": {
				"hello.json": [{
					"msgctxt"     : "",
					"msgid"       : "Hello, world!",
					"msgid_plural": "",
					"msgstr"      : ["你好, 世界!"]
				}]
			}
		}
	}`

gettext := gettext.New("hello", "???", jsonData).SetLanguage("zh_CN")
fmt.Println(gettext.Gettext("Hello, world!"))
Output:

你好, 世界!
Example (MultiLang)
zh := gettext.New("hello", "./examples/locale").SetLanguage("zh_CN")
tw := gettext.New("hello", "./examples/locale").SetLanguage("zh_TW")

fmt.Println(zh.PGettext(
	"code.google.com/p/gettext-go/examples/hi.SayHi",
	"pkg hi: Hello, world!",
))

fmt.Println(tw.PGettext(
	"code.google.com/p/gettext-go/examples/hi.SayHi",
	"pkg hi: Hello, world!",
))
Output:

来自"Hi"包的问候: 你好, 世界!(ctx:code.google.com/p/gettext-go/examples/hi.SayHi)
來自"Hi"包的問候: 你好, 世界!(ctx:code.google.com/p/gettext-go/examples/hi.SayHi)
Example (Zip)
gettext := gettext.New("hello", "./examples/locale.zip").SetLanguage("zh_CN")
fmt.Println(gettext.Gettext("Hello, world!"))
Output:

你好, 世界!
Example (ZipData)
zipData, err := ioutil.ReadFile("./examples/locale.zip")
if err != nil {
	log.Fatal(err)
}

gettext := gettext.New("hello", "???", zipData).SetLanguage("zh_CN")
fmt.Println(gettext.Gettext("Hello, world!"))
Output:

你好, 世界!

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	DefaultLanguage string = getDefaultLanguage() // use $(LC_MESSAGES) or $(LANG) or "default"
)

Functions

func BindLocale

func BindLocale(g Gettexter)

BindLocale sets and queries program's domains.

Examples:

BindLocale(New("poedit", "locale")) // bind "poedit" domain

Use zip file:

BindLocale(New("poedit", "locale.zip"))          // bind "poedit" domain
BindLocale(New("poedit", "locale.zip", zipData)) // bind "poedit" domain

Use FileSystem:

BindLocale(New("poedit", "name", OS("path/to/dir"))) // bind "poedit" domain
BindLocale(New("poedit", "name", OS("path/to.zip"))) // bind "poedit" domain

func DGetdata

func DGetdata(domain, name string) []byte

DGetdata like Getdata(), but looking up the resource in the specified domain.

Examples:

func Foo() {
	msg := gettext.DGetdata("hello", "poems.txt")
}

func DGettext

func DGettext(domain, msgid string) string

DGettext like Gettext(), but looking up the message in the specified domain.

Examples:

func Foo() {
	msg := gettext.DGettext("poedit", "Hello")
}

func DNGettext

func DNGettext(domain, msgid, msgidPlural string, n int) string

DNGettext like NGettext(), but looking up the message in the specified domain.

Examples:

func Foo() {
	msg := gettext.PNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2)
}

func DPGettext

func DPGettext(domain, msgctxt, msgid string) string

DPGettext like PGettext(), but looking up the message in the specified domain.

Examples:

func Foo() {
	msg := gettext.DPGettext("poedit", "gettext-go.example", "Hello")
}

func DPNGettext

func DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string

DPNGettext like PNGettext(), but looking up the message in the specified domain.

Examples:

func Foo() {
	msg := gettext.DPNGettext("poedit", "gettext-go.example", "%d people", "%d peoples", 2)
}

func Getdata

func Getdata(name string) []byte

Getdata attempt to translate a resource file into the user's native language, by looking up the translation in a message catalog.

Examples:

func Foo() {
	Textdomain("hello")
	BindLocale("hello", "locale.zip", nilOrZipData)
	poems := gettext.Getdata("poems.txt")
}

func Gettext

func Gettext(msgid string) string

Gettext attempt to translate a text string into the user's native language, by looking up the translation in a message catalog.

It use the caller's function name as the msgctxt.

Examples:

func Foo() {
	msg := gettext.Gettext("Hello") // msgctxt is ""
}

func NGettext

func NGettext(msgid, msgidPlural string, n int) string

NGettext attempt to translate a text string into the user's native language, by looking up the appropriate plural form of the translation in a message catalog.

It use the caller's function name as the msgctxt.

Examples:

func Foo() {
	msg := gettext.NGettext("%d people", "%d peoples", 2)
}

func PGettext

func PGettext(msgctxt, msgid string) string

PGettext attempt to translate a text string into the user's native language, by looking up the translation in a message catalog.

Examples:

func Foo() {
	msg := gettext.PGettext("gettext-go.example", "Hello") // msgctxt is "gettext-go.example"
}

func PNGettext

func PNGettext(msgctxt, msgid, msgidPlural string, n int) string

PNGettext attempt to translate a text string into the user's native language, by looking up the appropriate plural form of the translation in a message catalog.

Examples:

func Foo() {
	msg := gettext.PNGettext("gettext-go.example", "%d people", "%d peoples", 2)
}

func SetDomain

func SetDomain(domain string) string

SetDomain sets and retrieves the current message domain.

If the domain is not empty string, set the new domains.

If the domain is empty string, don't change anything.

Returns is the all used domains.

Examples:

SetDomain("poedit") // set domain: poedit
SetDomain("")       // get domain: return poedit

func SetLanguage

func SetLanguage(lang string) string

SetLanguage sets and queries the program's current lang.

If the lang is not empty string, set the new locale.

If the lang is empty string, don't change anything.

Returns is the current locale.

Examples:

SetLanguage("")      // get locale: return DefaultLocale
SetLanguage("zh_CN") // set locale: return zh_CN
SetLanguage("")      // get locale: return zh_CN

Types

type FileSystem

type FileSystem interface {
	LocaleList() []string
	LoadMessagesFile(domain, lang, ext string) ([]byte, error)
	LoadResourceFile(domain, lang, name string) ([]byte, error)
	String() string
}

func NewFS

func NewFS(name string, x interface{}) FileSystem

func NilFS

func NilFS(name string) FileSystem

func OS

func OS(root string) FileSystem

func ZipFS

func ZipFS(r *zip.Reader, name string) FileSystem

type Gettexter

type Gettexter interface {
	FileSystem() FileSystem

	GetDomain() string
	SetDomain(domain string) Gettexter

	GetLanguage() string
	SetLanguage(lang string) Gettexter

	Gettext(msgid string) string
	PGettext(msgctxt, msgid string) string

	NGettext(msgid, msgidPlural string, n int) string
	PNGettext(msgctxt, msgid, msgidPlural string, n int) string

	DGettext(domain, msgid string) string
	DPGettext(domain, msgctxt, msgid string) string
	DNGettext(domain, msgid, msgidPlural string, n int) string
	DPNGettext(domain, msgctxt, msgid, msgidPlural string, n int) string

	Getdata(name string) []byte
	DGetdata(domain, name string) []byte
}

func New

func New(domain, path string, data ...interface{}) Gettexter

New create Interface use default language.

Directories

Path Synopsis
cmd
xgettext-go
The xgettext-go program extracts translatable strings from Go packages.
The xgettext-go program extracts translatable strings from Go packages.
This is a gettext-go exmaple.
This is a gettext-go exmaple.
hi
Package hi is a example pkg.
Package hi is a example pkg.
Package mo provides support for reading and writing GNU MO file.
Package mo provides support for reading and writing GNU MO file.
Package plural provides standard plural formulas.
Package plural provides standard plural formulas.
Package po provides support for reading and writing GNU PO file.
Package po provides support for reading and writing GNU PO file.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL