Categorygithub.com/leonelquinteros/gotext
modulepackage
1.7.0
Repository: https://github.com/leonelquinteros/gotext.git
Documentation: pkg.go.dev

# README

GitHub release MIT license Gotext build Go Report Card PkgGoDev

Gotext

GNU gettext utilities for Go.

Features

  • Implements GNU gettext support in native Go.
  • Complete support for PO files including:
  • Support for MO files.
  • Thread-safe: This package is safe for concurrent use across multiple goroutines.
  • It works with UTF-8 encoding as it's the default for Go language.
  • Unit tests available.
  • Language codes are automatically simplified from the form en_UK to en if the first isn't available.
  • Ready to use inside Go templates.
  • Objects are serializable to []byte to store them in cache.
  • Support for Go Modules.

License

MIT license

Documentation

Refer to the Godoc package documentation at (https://godoc.org/github.com/leonelquinteros/gotext)

Installation

go get github.com/leonelquinteros/gotext
  • There are no requirements or dependencies to use this package.
  • No need to install GNU gettext utilities (unless specific needs of CLI tools).
  • No need for environment variables. Some naming conventions are applied but not needed.

Version vendoring

Stable releases use semantic versioning tagging on this repository.

You can rely on this to use your preferred vendoring tool or to manually retrieve the corresponding release tag from the GitHub repository.

NOTE: v1.5.0 contains a breaking change on how Po objects are initialised, see (https://github.com/leonelquinteros/gotext/issues/56)

Vendoring with Go Modules (Recommended)

Add github.com/leonelquinteros/gotext inside the require section in your go.mod file.

i.e.

require (
    github.com/leonelquinteros/gotext v1.4.0
)

Vendoring with gopkg.in

http://gopkg.in/leonelquinteros/gotext.v1

To get the latest v1 package stable release, execute:

go get gopkg.in/leonelquinteros/gotext.v1

Import as

import "gopkg.in/leonelquinteros/gotext.v1"

Refer to it as gotext.

Locales directories structure

The package will assume a directories structure starting with a base path that will be provided to the package configuration or to object constructors depending on the use, but either will use the same convention to lookup inside the base path.

Inside the base directory where will be the language directories named using the language and country 2-letter codes (en_US, es_AR, ...). All package functions can lookup after the simplified version for each language in case the full code isn't present but the more general language code exists. So if the language set is en_UK, but there is no directory named after that code and there is a directory named en, all package functions will be able to resolve this generalization and provide translations for the more general library.

The language codes are assumed to be ISO 639-1 codes (2-letter codes). That said, most functions will work with any coding standard as long the directory name matches the language code set on the configuration.

Then, there can be a LC_MESSAGES containing all PO files or the PO files themselves. A library directory structure can look like:

/path/to/locales
/path/to/locales/en_US
/path/to/locales/en_US/LC_MESSAGES
/path/to/locales/en_US/LC_MESSAGES/default.po
/path/to/locales/en_US/LC_MESSAGES/extras.po
/path/to/locales/en_UK
/path/to/locales/en_UK/LC_MESSAGES
/path/to/locales/en_UK/LC_MESSAGES/default.po
/path/to/locales/en_UK/LC_MESSAGES/extras.po
/path/to/locales/en_AU
/path/to/locales/en_AU/LC_MESSAGES
/path/to/locales/en_AU/LC_MESSAGES/default.po
/path/to/locales/en_AU/LC_MESSAGES/extras.po
/path/to/locales/es
/path/to/locales/es/default.po
/path/to/locales/es/extras.po
/path/to/locales/es_ES
/path/to/locales/es_ES/default.po
/path/to/locales/es_ES/extras.po
/path/to/locales/fr
/path/to/locales/fr/default.po
/path/to/locales/fr/extras.po

And so on...

Usage examples

Using package for single language/domain settings

For quick/simple translations you can use the package level functions directly.

import (
    "fmt"
    "github.com/leonelquinteros/gotext"
)

func main() {
    // Configure package
    gotext.Configure("/path/to/locales/root/dir", "en_UK", "domain-name")

    // Translate text from default domain
    fmt.Println(gotext.Get("My text on 'domain-name' domain"))

    // Translate text from a different domain without reconfigure
    fmt.Println(gotext.GetD("domain2", "Another text on a different domain"))
}

Using dynamic variables on translations

All translation strings support dynamic variables to be inserted without translate. Use the fmt.Printf syntax (from Go's "fmt" package) to specify how to print the non-translated variable inside the translation string.

import (
    "fmt"
    "github.com/leonelquinteros/gotext"
)

func main() {
    // Configure package
    gotext.Configure("/path/to/locales/root/dir", "en_UK", "domain-name")

    // Set variables
    name := "John"

    // Translate text with variables
    fmt.Println(gotext.Get("Hi, my name is %s", name))
}

Using Locale object

When having multiple languages/domains/libraries at the same time, you can create Locale objects for each variation so you can handle each settings on their own.

import (
    "fmt"
    "github.com/leonelquinteros/gotext"
)

func main() {
    // Create Locale with library path and language code
    l := gotext.NewLocale("/path/to/locales/root/dir", "es_UY")

    // Load domain '/path/to/locales/root/dir/es_UY/default.po'
    l.AddDomain("default")

    // Translate text from default domain
    fmt.Println(l.Get("Translate this"))

    // Load different domain
    l.AddDomain("translations")

    // Translate text from domain
    fmt.Println(l.GetD("translations", "Translate this"))
}

This is also helpful for using inside templates (from the "text/template" package), where you can pass the Locale object to the template. If you set the Locale object as "Loc" in the template, then the template code would look like:

{{ .Loc.Get "Translate this" }}

Using the Po object to handle .po files and PO-formatted strings

For when you need to work with PO files and strings, you can directly use the Po object to parse it and access the translations in there in the same way.

import (
    "fmt"
    "github.com/leonelquinteros/gotext"
)

func main() {
    // Set PO content
    str := `
msgid "Translate this"
msgstr "Translated text"

msgid "Another string"
msgstr ""

msgid "One with var: %s"
msgstr "This one sets the var: %s"
`

    // Create Po object
    po := gotext.NewPo()
    po.Parse(str)

    fmt.Println(po.Get("Translate this"))
}

Use plural forms of translations

PO format supports defining one or more plural forms for the same translation. Relying on the PO file headers, a Plural-Forms formula can be set on the translation file as defined in (https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html)

import (
    "fmt"
    "github.com/leonelquinteros/gotext"
)

func main() {
    // Set PO content
    str := `
msgid ""
msgstr ""

# Header below
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

msgid "Translate this"
msgstr "Translated text"

msgid "Another string"
msgstr ""

msgid "One with var: %s"
msgid_plural "Several with vars: %s"
msgstr[0] "This one is the singular: %s"
msgstr[1] "This one is the plural: %s"
`

    // Create Po object
    po := new(gotext.Po)
    po.Parse(str)

    fmt.Println(po.GetN("One with var: %s", "Several with vars: %s", 54, v))
    // "This one is the plural: Variable"
}

Contribute

  • Please, contribute.
  • Use the package on your projects.
  • Report issues on Github.
  • Send pull requests for bugfixes and improvements.
  • Send proposals on Github issues.

# Packages

No description provided by the author
Package plurals is the pluralform compiler to get the correct translation id of the plural string */.

# Functions

Appendf applies text formatting only when needed to parse variables.
Configure sets all configuration variables to be used at package level and reloads the corresponding Translation file.
No description provided by the author
Get uses the default domain globally set to return the corresponding Translation of a given string.
GetC uses the default domain globally set to return the corresponding Translation of the given string in the given context.
GetD returns the corresponding Translation in the given domain for a given string.
GetDC returns the corresponding Translation in the given domain for the given string in the given context.
GetDomain is the domain getter for the package configuration.
GetLanguage returns the language gotext will translate into.
GetLanguages returns all languages that have been supplied.
GetLibrary is the library getter for the package configuration.
No description provided by the author
GetN retrieves the (N)th plural form of Translation for the given string in the default domain.
GetNC retrieves the (N)th plural form of Translation for the given string in the given context in the default domain.
GetND retrieves the (N)th plural form of Translation in the given domain for a given string.
GetNDC retrieves the (N)th plural form of Translation in the given domain for a given string.
GetStorage is the locale storage getter for the package configuration.
IsTranslated reports whether a string is translated in given languages.
IsTranslatedC reports whether a context string is translated in given languages.
IsTranslatedD reports whether a domain string is translated in given languages.
IsTranslatedDC reports whether a domain context string is translated in given languages.
IsTranslatedN reports whether a plural string is translated in given languages.
IsTranslatedNC reports whether a plural context string is translated in given languages.
IsTranslatedND reports whether a plural domain string is translated in any of given languages.
IsTranslatedNDC reports whether a plural domain context string is translated in any of given languages.
No description provided by the author
NewLocale creates and initializes a new Locale object for a given language.
NewLocaleFS returns a Locale working with a fs.FS.
NewLocaleFSWithPath returns a Locale working with a fs.FS on a p path folder.
NewMo should always be used to instantiate a new Mo object.
NewMoFS works like NewMO but adds an optional fs.FS.
NewPo should always be used to instantiate a new Po object.
NewPoFS works like NewPO but adds an optional fs.FS.
NewTranslation returns the Translation object and initialized it.
No description provided by the author
NPrintf support named format NPrintf("%(name)s is Type %(type)s", map[string]interface{}{"name": "Gotext", "type": "struct"}).
Printf applies text formatting only when needed to parse variables.
SetDomain sets the name for the domain to be used at package level.
SetLanguage sets the language code (or colon separated language codes) to be used at package level.
SetLibrary sets the root path for the locale directories and files to be used at package level.
SetLocales allows for overriding the global Locale objects with ones built manually with NewLocale().
SetStorage allows overriding the global Locale object with one built manually with NewLocale().
SimplifiedLocale simplified locale like " en_US"/"de_DE "/en_US.UTF-8/zh_CN/zh_TW/el_GR@euro/..
Sprintf support named format Sprintf("%(name)s is Type %(type)s", map[string]interface{}{"name": "Gotext", "type": "struct"}).

# Constants

EotSeparator msgctxt and msgid separator.
MoMagicBigEndian encoding.
MoMagicLittleEndian encoding.
NulSeparator msgid and msgstr separator.

# Variables

No description provided by the author

# Structs

Domain has all the common functions for dealing with a gettext domain it's initialized with a GettextFile (which represents either a Po or Mo file).
Locale wraps the entire i18n collection for a single language (locale) It's used by the package functions, but it can also be used independently to handle multiple languages at the same time by working with this object.
LocaleEncoding is used as intermediary storage to encode Locale objects to Gob.
Mo parses the content of any MO file and provides all the Translation functions needed.
Po parses the content of any PO file and provides all the Translation functions needed.
No description provided by the author
Translation is the struct for the Translations parsed via Po or Mo files and all coming parsers.
TranslatorEncoding is used as intermediary storage to encode Translator objects to Gob.

# Interfaces

No description provided by the author
IsTranslatedDomainIntrospector is able to determine whether a given string is translated.
IsTranslatedIntrospector is able to determine whether a given string is translated.
Translator interface is used by Locale and Po objects.Translator It contains all methods needed to parse translation sources and obtain corresponding translations.

# Type aliases

Preserve MIMEHeader behaviour, without the canonicalisation.