Standard library · Text

i18n

A multilingual program: translating messages, placing values into them and choosing singular or plural.

import i18n
On this page
  1. Types
  2. Functions

If your program has to speak several languages, do not write the messages into the code. Put them in a translation catalog under a key, and ask for the user's language when you display one.

Every catalog has a fallback language. When a message has no translation in the user's language, the fallback is shown, and when that is missing too, the key itself; so the program never shows an empty message.

Types

Catalog

struct Catalog
A catalog of translations. Build one with New and release it with Free.
NameTypeDescription
keysVectorThe stored keys, in the form "language:key".
valsVectorThe translations, in the same order as the keys.
fallbackstr = "en"The fallback language.
i18n-Catalog.salam
import i18n

func main:
    mut c := i18n.New("en")
    defer i18n.Free(c)
    i18n.Set(c, "en", "hello", "Hello")
    i18n.Set(c, "fa", "hello", "سلام")
    i18n.Set(c, "en", "bye", "Goodbye")
    println i18n.T(c, "fa", "hello"), i18n.T(c, "fa", "bye"), i18n.T(c, "fa", "missing")
    println i18n.Has(c, "fa", "bye"), i18n.RawGet(c, "fa", "bye") == ""
    println c.fallback
end
Outputسلام Goodbye missing false true en

Functions

New

func New(default_locale: str): Catalog
Creates an empty catalog with the given fallback language.

The example for this item is shown with the ones above: i18n-Catalog.salam

Set

func Set(c &: Catalog, locale: str, key: str, val: str)
Records the translation of a key for a language, replacing any earlier one.

The example for this item is shown with the ones above: i18n-Catalog.salam

Has

func Has(c &: Catalog, locale: str, key: str): bool
True when a translation is recorded for this language and key. It does not look at the fallback language.

The example for this item is shown with the ones above: i18n-Catalog.salam

RawGet

func RawGet(c &: Catalog, locale: str, key: str): str
Returns the recorded translation with no substitution at all, or an empty string when there is none.

The example for this item is shown with the ones above: i18n-Catalog.salam

T

func T(c &: Catalog, locale: str, key: str): str
Returns the translation of the key, or the fallback language's translation, or, failing that, the key itself.

The example for this item is shown with the ones above: i18n-Catalog.salam

Interpolate

func Interpolate(msg: str, param_names: Vector<str>, param_vals: Vector<str>): str
Replaces every {name} in the message with the value of that name. The names and the values are given in two vectors in the same order.
i18n-Tf.salam
import i18n

func main:
    mut c := i18n.New("en")
    defer i18n.Free(c)
    i18n.Set(c, "en", "greet", "Hello {name}, you have {n} new messages")
    mut names := Vector {} as Vector<str>
    mut values := Vector {} as Vector<str>
    defer names.free()
    defer values.free()
    names.push("name")
    names.push("n")
    values.push("Maryam")
    values.push("3")
    println i18n.Tf(c, "en", "greet", names, values)
    println i18n.Interpolate("{name} and {name} again", names, values)
end
OutputHello Maryam, you have 3 new messages Maryam and Maryam again

Tf

func Tf(c &: Catalog, locale: str, key: str, param_names: Vector<str>, param_vals: Vector<str>): str
Translation and interpolation in one step.

The example for this item is shown with the ones above: i18n-Tf.salam

Plural

func Plural(c &: Catalog, locale: str, key: str, n: i64): str
Chooses the right form of a message for the number n: the key .one for one and .other for the rest. It does not place the number in the message itself; use Interpolate for that. Languages that need only one form can define .other alone.
i18n-Plural.salam
import i18n
import io

func main:
    mut c := i18n.New("en")
    defer i18n.Free(c)
    io.WriteFile("en.txt", "apple.one = one apple\napple.other = {n} apples\n")
    println i18n.LoadLocale(c, "en", "en.txt")
    mut names := Vector {} as Vector<str>
    defer names.free()
    names.push("n")
    each n in [1, 5]:
        mut values := Vector {} as Vector<str>
        values.push("" + n)
        println i18n.Interpolate(i18n.Plural(c, "en", "apple", n), names, values)
        values.free()
    end
    println i18n.DetectLocale().len() > 0
end
Output2 one apple 5 apples true

LoadLocale

func LoadLocale(c &: Catalog, locale: str, path: str): int
Loads the translations of one language from a file of key = value lines and returns how many keys were read.

The example for this item is shown with the ones above: i18n-Plural.salam

DetectLocale

func DetectLocale(): str
Guesses the user's language from the environment: SALAM_LOCALE first, then LANG and LC_ALL. When none is set it returns en.

The example for this item is shown with the ones above: i18n-Plural.salam

Free

func Free(c &: Catalog)
Releases the catalog's memory.

The example for this item is shown with the ones above: i18n-Catalog.salam