LiveSvelteGettext.Plurals (LiveSvelteGettext v0.2.0)
View SourceReads translated plural forms straight from a backend's .po files.
Why this exists
Gettext's runtime API cannot give us an untranslated-but-localized plural
form. Gettext.Backend.lngettext/7 unconditionally overwrites the :count
binding with the numeric n it was called with:
var!(bindings) = Map.put(bindings, :count, n)So there is no way to ask it for the Spanish plural of "%{count} items"
with the %{count} placeholder still intact - and the placeholder is exactly
what has to reach the browser, because interpolation happens client-side with
the real count.
Before this module existed, all_translations/1 worked around that by
returning the raw English msgid/msgid_plural, which meant plurals were
never translated at all.
Reading the .po file gives us the exact msgstr for every plural form,
placeholders untouched.
Plural form selection
The browser has to pick a form from a list. Gettext identifies forms by a
numeric index whose meaning is language-specific, while Intl.PluralRules
in the browser speaks CLDR category names ("one", "few", "many", ...).
Rather than shipping a rule evaluator, we send a small probe table: a handful
of representative counts and the gettext form index each one selects. The
client asks Intl.PluralRules for the category of its count, finds a probe
with the same category, and uses that probe's index. Both systems partition
counts along the same linguistic lines, so a matching category implies a
matching form.
Failure behaviour
Every function here degrades to :error or a safe default rather than
raising. A missing, unreadable or malformed .po file must never take down
a page render - it just means the untranslated strings are used.
Summary
Types
Map of {msgid, msgid_plural} to its translated forms
Translated plural forms, ordered by gettext form index
Functions
Loads the plural messages of a backend's .po file for locale.
Returns the number of plural forms locale has, defaulting to 2.
Returns the probe table for locale as a list of [count, form_index] pairs.
Types
Functions
Loads the plural messages of a backend's .po file for locale.
Returns a map keyed by {msgid, msgid_plural}. Messages with any empty
plural form are skipped, matching Gettext's own behaviour of falling back to
the original string when a translation is incomplete.
Returns an empty map when the locale has no .po file, when it cannot be
read, or when the backend does not expose the Gettext introspection API.
Results are cached in :persistent_term, keyed by the file's size and
modification time, so an edited .po file is picked up without a restart.
@spec nplurals(module(), String.t()) :: pos_integer()
Returns the number of plural forms locale has, defaulting to 2.
@spec probes(module(), String.t()) :: [[non_neg_integer()]]
Returns the probe table for locale as a list of [count, form_index] pairs.
The client uses this to map a count to a gettext plural form index. See the module documentation for how the mapping works.
Falls back to the English rule (0 for one, 1 for anything else) when the
locale's plural rules cannot be determined.