fastgettext

package module
v0.0.0-...-8beb2fb Latest Latest
Warning

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

Go to latest
Published: Jul 9, 2026 License: BSD-3-Clause Imports: 10 Imported by: 0

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:

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

Constants

This section is empty.

Variables

View Source
var Default = New()

Default is the shared instance used by the package-level functions.

View Source
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

func BestLocaleIn(locales string) string

BestLocaleIn negotiates against the Default instance's available locales.

func DefaultLocale

func DefaultLocale() string

DefaultLocale returns the Default instance's default locale.

func DefaultPluralRule

func DefaultPluralRule(n int) int

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 Gettext

func Gettext(key string) string

Gettext translates key on the Default instance.

func GettextDefault

func GettextDefault(key, fallback string) string

GettextDefault translates key on the Default instance with a fallback.

func KeyExist

func KeyExist(key string) bool

KeyExist reports key existence on the Default instance.

func Locale

func Locale() string

Locale returns the Default instance's current locale.

func NGettext

func NGettext(singular, plural string, n int) string

NGettext translates a two-form plural on the Default instance.

func NGettextForms

func NGettextForms(keys []string, n int) string

NGettextForms translates a multi-form plural on the Default instance.

func NPGettext

func NPGettext(context, singular, plural string, n int) string

NPGettext translates a contextual plural on the Default instance.

func NSGettext

func NSGettext(keys []string, n int) string

NSGettext translates a namespaced plural on the Default instance.

func PGettext

func PGettext(context, key string) string

PGettext translates key within context on the Default instance.

func PGettextSep

func PGettextSep(context, key, separator string) string

PGettextSep is PGettext with an explicit separator on the Default instance.

func Reload

func Reload() error

Reload reloads the Default instance.

func SGettext

func SGettext(key string) string

SGettext translates key with a "|" namespace on the Default instance.

func SGettextSep

func SGettextSep(key, separator string) string

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 SetLocale

func SetLocale(newLocale string) string

SetLocale sets the Default instance's locale and returns the applied one.

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.

func (*BaseRepository) Reload

func (r *BaseRepository) Reload() error

Reload is a no-op.

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

func ParseMO(data []byte) (*Catalog, error)

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

func ParsePO(data []byte) (*Catalog, error)

ParsePO parses the textual GNU gettext .po format into a Catalog using the default options.

func ParsePOOptions

func ParsePOOptions(data []byte, opts POOptions) (*Catalog, error)

ParsePOOptions parses .po data with explicit options.

func (*Catalog) Get

func (c *Catalog) Get(key string) (string, bool)

Get returns the translation for key and whether it was present.

func (*Catalog) Plural

func (c *Catalog) Plural(keys ...string) []string

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.

func (*Catalog) Set

func (c *Catalog) Set(key, value string)

Set stores a raw msgid -> msgstr mapping. Plural entries use keys and values whose forms are joined by NUL (see ParsePO / ParseMO).

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 New

func New() *Instance

New returns an empty Instance.

func (*Instance) AddTextDomain

func (i *Instance) AddTextDomain(name string, repo Repository)

AddTextDomain registers repo under the domain name.

func (*Instance) AvailableLocales

func (i *Instance) AvailableLocales() []string

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

func (i *Instance) BestLocaleIn(locales string) string

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

func (i *Instance) DefaultLocale() string

DefaultLocale returns the default locale.

func (*Instance) DefaultTextDomain

func (i *Instance) DefaultTextDomain() string

DefaultTextDomain returns the default text domain.

func (*Instance) ExpireCacheFor

func (i *Instance) ExpireCacheFor(key string)

ExpireCacheFor drops the cached translation of key for the current domain/locale.

func (*Instance) Gettext

func (i *Instance) Gettext(key string) string

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

func (i *Instance) GettextDefault(key, fallback string) string

GettextDefault translates key, returning fallback instead of key when there is no translation (the block form of _).

func (*Instance) KeyExist

func (i *Instance) KeyExist(key string) bool

KeyExist reports whether the current repository has a translation for key.

func (*Instance) Locale

func (i *Instance) Locale() string

Locale returns the current locale, falling back to the default locale, the first available locale, then "en".

func (*Instance) NGettext

func (i *Instance) NGettext(singular, plural string, n int) string

NGettext translates a two-form plural (the n_ helper), selecting singular or plural by the current plural rule applied to n.

func (*Instance) NGettextForms

func (i *Instance) NGettextForms(keys []string, n int) string

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

func (i *Instance) NPGettext(context, singular, plural string, n int) string

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

func (i *Instance) NPGettextSep(context, singular, plural string, n int, separator string) string

NPGettextSep is Instance.NPGettext with an explicit context separator.

func (*Instance) NSGettext

func (i *Instance) NSGettext(keys []string, n int) string

NSGettext translates a plural whose msgids carry a "|" namespace (the ns_ helper); when untranslated it returns the segment after the last "|".

func (*Instance) PGettext

func (i *Instance) PGettext(context, key string) string

PGettext translates key within context (the p_ helper), joining them with the U+0004 context separator; the untranslated fallback is key.

func (*Instance) PGettextSep

func (i *Instance) PGettextSep(context, key, separator string) string

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

func (i *Instance) Reload() error

Reload clears the translation cache and reloads every registered repository.

func (*Instance) SGettext

func (i *Instance) SGettext(key string) string

SGettext translates key and, when untranslated, returns the segment after the last "|" (the s_ helper).

func (*Instance) SGettextSep

func (i *Instance) SGettextSep(key, separator string) string

SGettextSep is Instance.SGettext with an explicit namespace separator.

func (*Instance) SetAvailableLocales

func (i *Instance) SetAvailableLocales(locales []string)

SetAvailableLocales sets the accepted locales; pass nil to accept anything.

func (*Instance) SetDefaultAvailableLocales

func (i *Instance) SetDefaultAvailableLocales(locales []string)

SetDefaultAvailableLocales sets the fallback accepted-locale list.

func (*Instance) SetDefaultLocale

func (i *Instance) SetDefaultLocale(newLocale string)

SetDefaultLocale negotiates and stores the default locale.

func (*Instance) SetDefaultTextDomain

func (i *Instance) SetDefaultTextDomain(name string)

SetDefaultTextDomain sets the default text domain.

func (*Instance) SetLocale

func (i *Instance) SetLocale(newLocale string) string

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

func (i *Instance) SetTextDomain(name string)

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

func (i *Instance) TextDomain() string

TextDomain returns the current text domain (or the default when unset).

func (*Instance) WithDomain

func (i *Instance) WithDomain(name string, fn func())

WithDomain runs fn with the text domain temporarily set to name.

func (*Instance) WithLocale

func (i *Instance) WithLocale(temp string, fn func())

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) Get

func (r *MORepository) Get(locale, key string) (string, bool)

func (*MORepository) Plural

func (r *MORepository) Plural(locale string, keys ...string) []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) Get

func (r *MemoryRepository) Get(locale, key string) (string, bool)

func (*MemoryRepository) Name

func (r *MemoryRepository) Name() string

Name returns the text-domain name.

func (*MemoryRepository) Plural

func (r *MemoryRepository) Plural(locale string, keys ...string) []string

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) Get

func (r *PORepository) Get(locale, key string) (string, bool)

func (*PORepository) Plural

func (r *PORepository) Plural(locale string, keys ...string) []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

type PluralRule func(n int) int

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) Get

func (r *TestRepository) Get(locale, key string) (string, bool)

func (*TestRepository) Plural

func (r *TestRepository) Plural(locale string, keys ...string) []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.

Jump to

Keyboard shortcuts

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