ngettext
This is an implementation of ngettext
function from standard GNU gettext. But also its standard behavior can be
extended by some extra configuration for handling different number of plural forms than 2. By default it works as
expected with 2 plural forms. So you can use it even when you don't have actual translations, just for having support
for plural forms in your code.
Live demo
this demo works without the transpilation step, consider using
babel-plugin-ttag
for production usage
https://jsfiddle.net/AlexMost/mc2pd1on/2/
Usage:
import { ngettext, msgid } from 'ttag'
function test(n) {
return ngettext(msgid`${n} time clicked`, `${n} times clicked`, n)
}
This example works out of the box without no extra configuration for ttag plugin.
You may noticed that the first argument for ngettext
is tagged with msgid
tag.
This may seem a little bit weird, but this is the only way to find translations by msgid without code
transpilation with babel plugin. User friendly checks on extract and resolve steps will not let you forgive about that.
More details about why we are using msgid
tag are here.
ngettext format
Valid:
ngettext(msgid`${n} time clicked`, `${n} times clicked`, n)
ngettext(msgid`${1} time clicked`, `${1} times clicked`, 1)
ngettext(msgid`${this.count} time clicked`, `${this.count} times clicked`, this.count)
Invalid:
ngettext(msgid`${n} time clicked`, `${n} times clicked`) // plural number argument is missing
ngettext(`${n} time clicked`, `${n} times clicked`, n) // msgid tag for the first argument is missing
// only identifiers and member expressions are allowed inside translated templates.
ngettext(msgid`${fn()} time clicked`, `${fn()} times clicked`, fn())
.po
extraction
We will extract this from the example above:
#: src/ngettextDemo.js:19
msgid "${ n } time clicked"
msgid_plural "${ n } times clicked"
msgstr[0] ""
msgstr[1] ""
Resolve translations
Assume that translator added translations to our previous extracted entry:
#: src/ngettextDemo.js:19
msgid "${ n } time clicked"
msgid_plural "${ n } times clicked"
msgstr[0] "${ n } time clicked [translated]"
msgstr[1] "${ n } times clicked [translated]"
The resulting code (after transpilation will look like):
"use strict";
function _tag_ngettext(n, args) {
return args[+(n != 1)];
}
function test() {
return _tag_ngettext(n, [ n + " time clicked [translated]", n + " times clicked [translated]" ]));
}
There is a new extra function in our file - _tag_ngettext
, but you don't need to worry much about it, because this
function is autogenerated by ttag and may change in future without requiring any changes to your code.
Plural forms that are different from default (English)
It is possible that your are using different language than English in strings in the sources. And here is the point
when usage of ngettext
becomes not so clear. For instance, you decided to write strings in Ukrainian,
because at the time of the first release it was a single language for your project.
At some point, you decided to localize your strings and want to use ngettext
for plurals.
Ukrainian language has 3 plural forms, but standard ngettext has only 2 arguments for them,
so which one of those 3 plural forms must be passed to ngettext
function?
ttag suggests a quite a nice solution for this problem.
By default ttag uses 'en' language (English), but if you want to use ngettext
with Ukrainian locale, you should call setDefaultLang for the library and defaultLang for the plugin accordingly.
setDefaultLang('uk');
// 3 forms will be extracted
ngettext(msgid`${ n }form1`, `${ n } form2`, `${ n } form3`, n);
Tip: you can check the official GNU gettext manual for language ISO codes.