Plural Forms with gotext
gotext selects plural translations using the catalog's GNU Gettext Plural-Forms header. This guide explains how to use plural forms in your Go code and PO files.
1. Using Plural Forms in Go
To handle plurals, use the GetN or GetND functions (the N stands for plural-aware).
Package-Level API
package main
import (
"fmt"
"github.com/leonelquinteros/gotext"
)
func main() {
gotext.Configure("locales", "en_US", "default")
apples := 5
// GetN(singular msgid, plural msgid, quantity, formatting arguments...)
fmt.Println(gotext.GetN("I have one apple.", "I have %d apples.", apples, apples))
}
2. Setting Up Your PO Files
Plural forms rely on the Plural-Forms header in your PO file. This header defines the number of plural forms for the language and the rule (a C-like expression) to select the correct form based on the quantity n.
Example: English (2 forms: singular/plural)
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "I have one apple."
msgid_plural "I have %d apples."
msgstr[0] "I have one apple."
msgstr[1] "I have %d apples."
Example: Polish (3 forms)
msgid ""
msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
msgid "I have one apple."
msgid_plural "I have %d apples."
msgstr[0] "Mam jedno jabłko."
msgstr[1] "Mam %d jabłka."
msgstr[2] "Mam %d jabłek."
3. How it Works
- Header Parsing: When
gotextloads a PO file, it parses thePlural-Formsheader. - Expression Evaluation: When
GetNis called,gotextevaluates the plural expression with the providedn. - Result Indexing: The evaluation result (0, 1, 2, etc.) is used as an index to select the correct
msgstr[n]from the translation entry.
The expression result is a numeric form index, not necessarily a boolean. For example, nplurals=3; plural=n % 3; selects forms 0, 1, and 2. Numeric expressions can also appear in ternary branches. Conditions use C truthiness: zero is false and any nonzero value is true; comparison and logical operators produce 0 or 1.
For more information on plural form rules for different languages, see the GNU Gettext manual.