Documentation
¶
Overview ¶
Package fastgettext is a pure-Go (no cgo, standard-library only) port of the Ruby fast_gettext gem: fast message translation with text domains, pluggable translation repositories, and gettext-style lookup helpers.
Catalogs and parsers ¶
A Catalog is an in-memory message catalog: a msgid -> msgstr map plus an optional per-locale plural rule. Catalogs are produced from the two GNU gettext on-disk formats:
- ParsePO reads the textual .po format.
- ParseMO reads the binary .mo format (both byte orders, revision 0/1).
Both understand the context separator (msgctxt, U+0004), plural entries (msgid/msgid_plural joined by NUL), and the "Plural-Forms" header, whose C-like expression is compiled by ParsePluralForms / ParsePluralExpr.
Repositories ¶
A Repository answers translation queries. Implementations:
- MemoryRepository: locale -> *Catalog, held in memory.
- MORepository / PORepository: load per-locale catalogs from an io/fs.FS (locale/LC_MESSAGES/<name>.mo, or locale/<name>.po).
- ChainRepository: try each member in turn.
- LoggerRepository: record every lookup (used inside a chain).
- TestRepository: a mutable in-memory repository convenient for tests.
- BaseRepository: the empty fallback that never translates anything.
Translation API ¶
An Instance holds the registered domains, the current text domain and locale, and the translation cache. Package-level functions (Gettext, NGettext, SGettext, PGettext, ...) operate on a shared Default instance, mirroring the way the Ruby FastGettext module is used.
State is guarded by a mutex and is instance-global; this differs from the Ruby gem, whose current locale / text domain are thread-local. WithLocale and WithDomain save and restore state around a callback but do not isolate concurrent goroutines.
Index ¶
- Variables
- func AddTextDomain(name string, repo Repository)
- func AvailableLocales() []string
- func BestLocaleIn(locales string) string
- func DefaultLocale() string
- func DefaultPluralRule(n int) int
- func DefaultTextDomain() string
- func ExpireCacheFor(key string)
- func Gettext(key string) string
- func GettextDefault(key, fallback string) string
- func KeyExist(key string) bool
- func Locale() string
- func NGettext(singular, plural string, n int) string
- func NGettextForms(keys []string, n int) string
- func NPGettext(context, singular, plural string, n int) string
- func NSGettext(keys []string, n int) string
- func PGettext(context, key string) string
- func PGettextSep(context, key, separator string) string
- func Reload() error
- func SGettext(key string) string
- func SGettextSep(key, separator string) string
- func SetAvailableLocales(locales []string)
- func SetDefaultAvailableLocales(locales []string)
- func SetDefaultLocale(newLocale string)
- func SetDefaultTextDomain(name string)
- func SetLocale(newLocale string) string
- func SetPluralisationRule(rule PluralRule)
- func SetTextDomain(name string)
- func SilenceErrors()
- func TextDomain() string
- func WithDomain(name string, fn func())
- func WithLocale(temp string, fn func())
- type BaseRepository
- type Catalog
- type ChainRepository
- func (r *ChainRepository) AvailableLocales() []string
- func (r *ChainRepository) Get(locale, key string) (string, bool)
- func (r *ChainRepository) Plural(locale string, keys ...string) []string
- func (r *ChainRepository) PluralisationRule(locale string) PluralRule
- func (r *ChainRepository) Reload() error
- type Instance
- func (i *Instance) AddTextDomain(name string, repo Repository)
- func (i *Instance) AvailableLocales() []string
- func (i *Instance) BestLocaleIn(locales string) string
- func (i *Instance) CurrentRepository() (Repository, error)
- func (i *Instance) DefaultLocale() string
- func (i *Instance) DefaultTextDomain() string
- func (i *Instance) ExpireCacheFor(key string)
- func (i *Instance) Gettext(key string) string
- func (i *Instance) GettextDefault(key, fallback string) string
- func (i *Instance) KeyExist(key string) bool
- func (i *Instance) Locale() string
- func (i *Instance) NGettext(singular, plural string, n int) string
- func (i *Instance) NGettextForms(keys []string, n int) string
- func (i *Instance) NPGettext(context, singular, plural string, n int) string
- func (i *Instance) NPGettextSep(context, singular, plural string, n int, separator string) string
- func (i *Instance) NSGettext(keys []string, n int) string
- func (i *Instance) PGettext(context, key string) string
- func (i *Instance) PGettextSep(context, key, separator string) string
- func (i *Instance) PluralisationRule() PluralRule
- func (i *Instance) Reload() error
- func (i *Instance) SGettext(key string) string
- func (i *Instance) SGettextSep(key, separator string) string
- func (i *Instance) SetAvailableLocales(locales []string)
- func (i *Instance) SetDefaultAvailableLocales(locales []string)
- func (i *Instance) SetDefaultLocale(newLocale string)
- func (i *Instance) SetDefaultTextDomain(name string)
- func (i *Instance) SetLocale(newLocale string) string
- func (i *Instance) SetPluralisationRule(rule PluralRule)
- func (i *Instance) SetTextDomain(name string)
- func (i *Instance) SilenceErrors()
- func (i *Instance) TextDomain() string
- func (i *Instance) WithDomain(name string, fn func())
- func (i *Instance) WithLocale(temp string, fn func())
- type LoggerRepository
- type MORepository
- type MemoryRepository
- func (r *MemoryRepository) AvailableLocales() []string
- func (r *MemoryRepository) Get(locale, key string) (string, bool)
- func (r *MemoryRepository) Name() string
- func (r *MemoryRepository) Plural(locale string, keys ...string) []string
- func (r *MemoryRepository) PluralisationRule(locale string) PluralRule
- func (r *MemoryRepository) Reload() error
- type POOptions
- type PORepository
- type PluralRule
- type Repository
- type TestRepository
- func (r *TestRepository) AvailableLocales() []string
- func (r *TestRepository) Get(locale, key string) (string, bool)
- func (r *TestRepository) Plural(locale string, keys ...string) []string
- func (r *TestRepository) PluralisationRule(locale string) PluralRule
- func (r *TestRepository) Reload() error
- func (r *TestRepository) SetPluralRule(locale string, rule PluralRule)
- func (r *TestRepository) Store(locale, key, value string)
- func (r *TestRepository) StorePlural(locale string, keys, forms []string)
Constants ¶
This section is empty.
Variables ¶
var Default = New()
Default is the shared instance used by the package-level functions.
var ErrNoTextDomain = errors.New("fastgettext: current text domain was not added, use AddTextDomain")
ErrNoTextDomain is returned by Instance.CurrentRepository when no repository is registered for the current text domain.
Functions ¶
func AddTextDomain ¶
func AddTextDomain(name string, repo Repository)
AddTextDomain registers repo on the Default instance.
func AvailableLocales ¶
func AvailableLocales() []string
AvailableLocales returns the Default instance's available locales.
func BestLocaleIn ¶
BestLocaleIn negotiates against the Default instance's available locales.
func DefaultLocale ¶
func DefaultLocale() string
DefaultLocale returns the Default instance's default locale.
func DefaultPluralRule ¶
DefaultPluralRule is fast_gettext's fallback rule (nplurals=2; plural=n!=1): index 1 for every count other than 1, index 0 for exactly 1.
func DefaultTextDomain ¶
func DefaultTextDomain() string
DefaultTextDomain returns the Default instance's default text domain.
func ExpireCacheFor ¶
func ExpireCacheFor(key string)
ExpireCacheFor drops a cached key on the Default instance.
func GettextDefault ¶
GettextDefault translates key on the Default instance with a fallback.
func NGettextForms ¶
NGettextForms translates a multi-form plural on the Default instance.
func PGettextSep ¶
PGettextSep is PGettext with an explicit separator on the Default instance.
func SGettextSep ¶
SGettextSep is SGettext with an explicit separator on the Default instance.
func SetAvailableLocales ¶
func SetAvailableLocales(locales []string)
SetAvailableLocales sets the Default instance's available locales.
func SetDefaultAvailableLocales ¶
func SetDefaultAvailableLocales(locales []string)
SetDefaultAvailableLocales sets the Default instance's default available locales.
func SetDefaultLocale ¶
func SetDefaultLocale(newLocale string)
SetDefaultLocale sets the Default instance's default locale.
func SetDefaultTextDomain ¶
func SetDefaultTextDomain(name string)
SetDefaultTextDomain sets the Default instance's default text domain.
func SetPluralisationRule ¶
func SetPluralisationRule(rule PluralRule)
SetPluralisationRule sets the Default instance's override plural rule.
func SetTextDomain ¶
func SetTextDomain(name string)
SetTextDomain sets the Default instance's current text domain.
func SilenceErrors ¶
func SilenceErrors()
SilenceErrors installs an empty repository on the Default instance.
func TextDomain ¶
func TextDomain() string
TextDomain returns the Default instance's current text domain.
func WithDomain ¶
func WithDomain(name string, fn func())
WithDomain runs fn under a temporary text domain on the Default instance.
func WithLocale ¶
func WithLocale(temp string, fn func())
WithLocale runs fn under a temporary locale on the Default instance.
Types ¶
type BaseRepository ¶
type BaseRepository struct {
// contains filtered or unexported fields
}
BaseRepository is the empty fallback repository: it never translates anything and never errors, mirroring fast_gettext's TranslationRepository::Base used by silence_errors.
func NewBaseRepository ¶
func NewBaseRepository(name string) *BaseRepository
NewBaseRepository returns an empty fallback repository.
func (*BaseRepository) AvailableLocales ¶
func (r *BaseRepository) AvailableLocales() []string
AvailableLocales is always empty.
func (*BaseRepository) Get ¶
func (r *BaseRepository) Get(string, string) (string, bool)
Get always reports a miss.
func (*BaseRepository) Plural ¶
func (r *BaseRepository) Plural(string, ...string) []string
Plural always reports no forms.
func (*BaseRepository) PluralisationRule ¶
func (r *BaseRepository) PluralisationRule(string) PluralRule
PluralisationRule is always nil.
type Catalog ¶
type Catalog struct {
// contains filtered or unexported fields
}
Catalog is an in-memory message catalog: a msgid -> msgstr map plus an optional per-locale plural rule parsed from the "Plural-Forms" header.
func NewCatalog ¶
func NewCatalog() *Catalog
NewCatalog returns an empty catalog ready for Catalog.Set.
func ParseMO ¶
ParseMO parses the bytes of a GNU gettext binary .mo file into a Catalog. Both byte orders and file-format revisions 0 and 1 are accepted. The empty msgid holds the metadata header, from which the plural rule is compiled.
func ParsePO ¶
ParsePO parses the textual GNU gettext .po format into a Catalog using the default options.
func ParsePOOptions ¶
ParsePOOptions parses .po data with explicit options.
func (*Catalog) Plural ¶
Plural returns the plural forms stored for the given keys (singular first), or nil when the combined key is absent.
func (*Catalog) PluralisationRule ¶
func (c *Catalog) PluralisationRule() PluralRule
PluralisationRule returns the catalog's plural rule, or nil when the header carried no Plural-Forms.
type ChainRepository ¶
type ChainRepository struct {
// Chain is the ordered list of repositories to consult.
Chain []Repository
// contains filtered or unexported fields
}
ChainRepository delegates to its members in order, returning the first hit, mirroring fast_gettext's TranslationRepository::Chain.
func NewChainRepository ¶
func NewChainRepository(name string, chain ...Repository) *ChainRepository
NewChainRepository builds a chain over the given repositories.
func (*ChainRepository) AvailableLocales ¶
func (r *ChainRepository) AvailableLocales() []string
AvailableLocales is the sorted union of every member's locales.
func (*ChainRepository) Get ¶
func (r *ChainRepository) Get(locale, key string) (string, bool)
Get returns the first member's translation for key.
func (*ChainRepository) Plural ¶
func (r *ChainRepository) Plural(locale string, keys ...string) []string
Plural returns the first member's non-empty plural forms.
func (*ChainRepository) PluralisationRule ¶
func (r *ChainRepository) PluralisationRule(locale string) PluralRule
PluralisationRule returns the first member's non-nil rule.
func (*ChainRepository) Reload ¶
func (r *ChainRepository) Reload() error
Reload reloads every member.
type Instance ¶
type Instance struct {
// contains filtered or unexported fields
}
Instance holds the registered text domains, the current text domain and locale, plural-rule override, available locales, and the translation cache. All state is guarded by a mutex; see the package doc for how this differs from the Ruby gem's thread-local storage.
func (*Instance) AddTextDomain ¶
func (i *Instance) AddTextDomain(name string, repo Repository)
AddTextDomain registers repo under the domain name.
func (*Instance) AvailableLocales ¶
AvailableLocales returns a copy of the configured available locales, or nil when none were set (meaning "any locale is acceptable" during negotiation).
func (*Instance) BestLocaleIn ¶
BestLocaleIn returns the best available locale for an Accept-Language style value, mirroring the gem's best_locale_in.
func (*Instance) CurrentRepository ¶
func (i *Instance) CurrentRepository() (Repository, error)
CurrentRepository returns the repository for the current text domain, or ErrNoTextDomain when none is registered.
func (*Instance) DefaultLocale ¶
DefaultLocale returns the default locale.
func (*Instance) DefaultTextDomain ¶
DefaultTextDomain returns the default text domain.
func (*Instance) ExpireCacheFor ¶
ExpireCacheFor drops the cached translation of key for the current domain/locale.
func (*Instance) Gettext ¶
Gettext translates key (the _ helper), returning key itself when there is no translation. When no text domain is configured it also returns key; use Instance.CurrentRepository for a strict check.
func (*Instance) GettextDefault ¶
GettextDefault translates key, returning fallback instead of key when there is no translation (the block form of _).
func (*Instance) KeyExist ¶
KeyExist reports whether the current repository has a translation for key.
func (*Instance) Locale ¶
Locale returns the current locale, falling back to the default locale, the first available locale, then "en".
func (*Instance) NGettext ¶
NGettext translates a two-form plural (the n_ helper), selecting singular or plural by the current plural rule applied to n.
func (*Instance) NGettextForms ¶
NGettextForms translates an arbitrary-arity plural: keys holds the singular and every plural form's msgid, and the plural rule applied to n picks a form.
func (*Instance) NPGettext ¶
NPGettext translates a two-form plural within context (the np_ helper); when the contextual form is missing it falls back to the plain plural.
func (*Instance) NPGettextSep ¶
NPGettextSep is Instance.NPGettext with an explicit context separator.
func (*Instance) NSGettext ¶
NSGettext translates a plural whose msgids carry a "|" namespace (the ns_ helper); when untranslated it returns the segment after the last "|".
func (*Instance) PGettext ¶
PGettext translates key within context (the p_ helper), joining them with the U+0004 context separator; the untranslated fallback is key.
func (*Instance) PGettextSep ¶
PGettextSep is Instance.PGettext with an explicit context separator.
func (*Instance) PluralisationRule ¶
func (i *Instance) PluralisationRule() PluralRule
PluralisationRule returns the effective plural rule: the override if set, else the current repository's rule, else DefaultPluralRule.
func (*Instance) Reload ¶
Reload clears the translation cache and reloads every registered repository.
func (*Instance) SGettext ¶
SGettext translates key and, when untranslated, returns the segment after the last "|" (the s_ helper).
func (*Instance) SGettextSep ¶
SGettextSep is Instance.SGettext with an explicit namespace separator.
func (*Instance) SetAvailableLocales ¶
SetAvailableLocales sets the accepted locales; pass nil to accept anything.
func (*Instance) SetDefaultAvailableLocales ¶
SetDefaultAvailableLocales sets the fallback accepted-locale list.
func (*Instance) SetDefaultLocale ¶
SetDefaultLocale negotiates and stores the default locale.
func (*Instance) SetDefaultTextDomain ¶
SetDefaultTextDomain sets the default text domain.
func (*Instance) SetLocale ¶
SetLocale negotiates newLocale against the available locales, stores the result, and returns the resulting current locale (which may differ, exactly like the gem's set_locale).
func (*Instance) SetPluralisationRule ¶
func (i *Instance) SetPluralisationRule(rule PluralRule)
SetPluralisationRule installs an override plural rule (nil clears it).
func (*Instance) SetTextDomain ¶
SetTextDomain sets the current text domain.
func (*Instance) SilenceErrors ¶
func (i *Instance) SilenceErrors()
SilenceErrors installs an empty BaseRepository for the current text domain if none is registered, so translation never errors.
func (*Instance) TextDomain ¶
TextDomain returns the current text domain (or the default when unset).
func (*Instance) WithDomain ¶
WithDomain runs fn with the text domain temporarily set to name.
func (*Instance) WithLocale ¶
WithLocale runs fn with the locale temporarily set to temp.
type LoggerRepository ¶
type LoggerRepository struct {
// Callback receives the looked-up key(s) on every Get/Plural.
Callback func(keys ...string)
// contains filtered or unexported fields
}
LoggerRepository records every lookup through Callback and never translates anything. Place it in a ChainRepository to discover untranslated keys.
func NewLoggerRepository ¶
func NewLoggerRepository(name string, callback func(keys ...string)) *LoggerRepository
NewLoggerRepository returns a logging repository using the given callback.
func (*LoggerRepository) AvailableLocales ¶
func (r *LoggerRepository) AvailableLocales() []string
AvailableLocales is always empty for a logger.
func (*LoggerRepository) Get ¶
func (r *LoggerRepository) Get(_ string, key string) (string, bool)
Get logs key and reports it as untranslated.
func (*LoggerRepository) Plural ¶
func (r *LoggerRepository) Plural(_ string, keys ...string) []string
Plural logs keys and reports no forms.
func (*LoggerRepository) PluralisationRule ¶
func (r *LoggerRepository) PluralisationRule(string) PluralRule
PluralisationRule is always nil for a logger.
func (*LoggerRepository) Reload ¶
func (r *LoggerRepository) Reload() error
Reload is a no-op for a logger.
type MORepository ¶
type MORepository struct {
// contains filtered or unexported fields
}
MORepository loads per-locale catalogs from an io/fs.FS, reading "<locale>/LC_MESSAGES/<name>.mo", mirroring fast_gettext's Mo repository.
func NewMORepository ¶
func NewMORepository(name string, fsys fs.FS) (*MORepository, error)
NewMORepository builds and loads a .mo repository over fsys.
func (*MORepository) AvailableLocales ¶
func (r *MORepository) AvailableLocales() []string
func (*MORepository) PluralisationRule ¶
func (r *MORepository) PluralisationRule(locale string) PluralRule
func (*MORepository) Reload ¶
func (r *MORepository) Reload() error
Reload re-reads every "<locale>/LC_MESSAGES/<name>.mo" file.
type MemoryRepository ¶
type MemoryRepository struct {
// contains filtered or unexported fields
}
MemoryRepository is a plain in-memory repository backed by a per-locale map of catalogs.
func NewMemoryRepository ¶
func NewMemoryRepository(name string, catalogs map[string]*Catalog) *MemoryRepository
NewMemoryRepository builds a repository from a locale -> *Catalog map. A nil map is treated as empty.
func (*MemoryRepository) AvailableLocales ¶
func (r *MemoryRepository) AvailableLocales() []string
func (*MemoryRepository) Name ¶
func (r *MemoryRepository) Name() string
Name returns the text-domain name.
func (*MemoryRepository) PluralisationRule ¶
func (r *MemoryRepository) PluralisationRule(locale string) PluralRule
func (*MemoryRepository) Reload ¶
func (r *MemoryRepository) Reload() error
Reload is a no-op for an in-memory repository.
type POOptions ¶
type POOptions struct {
// IgnoreFuzzy drops messages marked "#, fuzzy" (the metadata header is
// always kept). It defaults to false, matching fast_gettext's PoFile.
IgnoreFuzzy bool
}
POOptions tunes .po parsing.
type PORepository ¶
type PORepository struct {
// contains filtered or unexported fields
}
PORepository loads per-locale catalogs from an io/fs.FS, reading "<locale>/<name>.po", mirroring fast_gettext's Po repository.
func NewPORepository ¶
func NewPORepository(name string, fsys fs.FS) (*PORepository, error)
NewPORepository builds and loads a .po repository over fsys.
func (*PORepository) AvailableLocales ¶
func (r *PORepository) AvailableLocales() []string
func (*PORepository) PluralisationRule ¶
func (r *PORepository) PluralisationRule(locale string) PluralRule
func (*PORepository) Reload ¶
func (r *PORepository) Reload() error
Reload re-reads every "<locale>/<name>.po" file.
type PluralRule ¶
PluralRule maps a count n to the zero-based index of the plural form to use.
func ParsePluralExpr ¶
func ParsePluralExpr(expr string) (PluralRule, error)
ParsePluralExpr compiles a C-like plural-form expression over the single variable n into a PluralRule. Supported operators, in C precedence: ternary ?:, || , &&, == != , < > <= >= , + - , * / % , unary ! - +, integer literals, the variable n, and parentheses. Comparison and logical operators yield 0 or 1, matching C. Division or modulo by zero evaluates to 0 rather than panicking.
func ParsePluralForms ¶
func ParsePluralForms(header string) (PluralRule, error)
ParsePluralForms extracts and compiles the "plural=" expression from a gettext metadata header (the msgstr of the "" entry). It returns a nil rule and nil error when the header has no Plural-Forms line, and a non-nil error when the expression is present but cannot be compiled.
func PluralisationRule ¶
func PluralisationRule() PluralRule
PluralisationRule returns the Default instance's effective plural rule.
type Repository ¶
type Repository interface {
// Get returns the translation for key in locale and whether it exists.
Get(locale, key string) (string, bool)
// Plural returns the plural forms stored for keys in locale, or nil.
Plural(locale string, keys ...string) []string
// AvailableLocales lists the locales this repository can serve.
AvailableLocales() []string
// PluralisationRule returns the plural rule for locale, or nil.
PluralisationRule(locale string) PluralRule
// Reload re-reads any backing storage.
Reload() error
}
Repository answers translation queries for a text domain. Unlike the Ruby gem, whose repositories read the process-global current locale, these methods take the locale explicitly; the Instance passes its current locale.
func CurrentRepository ¶
func CurrentRepository() (Repository, error)
CurrentRepository returns the Default instance's current repository.
type TestRepository ¶
type TestRepository struct {
// contains filtered or unexported fields
}
TestRepository is a mutable in-memory repository convenient for tests: build it empty and add translations with TestRepository.Store / TestRepository.StorePlural.
func NewTestRepository ¶
func NewTestRepository(name string) *TestRepository
NewTestRepository returns an empty mutable repository.
func (*TestRepository) AvailableLocales ¶
func (r *TestRepository) AvailableLocales() []string
func (*TestRepository) PluralisationRule ¶
func (r *TestRepository) PluralisationRule(locale string) PluralRule
func (*TestRepository) Reload ¶
func (r *TestRepository) Reload() error
Reload is a no-op for a test repository.
func (*TestRepository) SetPluralRule ¶
func (r *TestRepository) SetPluralRule(locale string, rule PluralRule)
SetPluralRule installs a plural rule for locale.
func (*TestRepository) Store ¶
func (r *TestRepository) Store(locale, key, value string)
Store sets a singular translation for key in locale.
func (*TestRepository) StorePlural ¶
func (r *TestRepository) StorePlural(locale string, keys, forms []string)
StorePlural sets the plural forms for the given keys in locale.