17

See this example of _n(); function (http://codex.wordpress.org/Function_Reference/_n):

sprintf( _n('%d comment.', '%d comments.', $number, 'text-domain'), $number );

in English:

1 Comment
2 Comments

in languages such as Polish there is a different pattern and multiple plural forms:

1 Komentarz
2 Komentarze
3 Komentarze
4 Komentarze
5 Komentarzy
6 Komentarzy
...
21 Komentarzy
22 Komentarze
23 Komentarze
24 Komentarze
25 Komentarzy
...
31 Komentarzy
32 Komentarze
...
91 Komentarzy
92 Komentarze
...
111 Komentarzy
112 Komentarzy (!)
...
121 Komentarzy
122 Komentarze

I'm looking for some way to enable translators to set their own pattern if their language supports multiple plural forms. Can you think of any creative PHP approach to do this?

Some solution I can think of (but still translators will not be able to set any pattern):

if($number == 1){
    $message = __(‘1 Komentarz’ , ‘text-domain’);
}else if($number == 2){
    $message = __(‘2 Komentarze’ , ‘text-domain’);
}else if($number == 3){
    $message = __(‘3 Komentarze’ , ‘text-domain’);
}

EDIT: I found this in PO file for Polish: "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" but I still don't get how to prepare _n(); function to support that.

Atadj
  • 7,050
  • 19
  • 69
  • 94

2 Answers2

19

First, your locale file needs to have the definition of plural. As you added on the question, in Polish case you may see

"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"

or similar definition in (domain_name)-pl.po file.

Then, you need to prepare the translation for "%d Comment"/"%d Comments" in the .po file. For example,

msgid "%d Comment"
msgid_plural "%d Comments"
msgstr[0] "%d Komentarz"
msgstr[1] "%d Komentarze"
msgstr[2] "%d Komentarzy"

Please compile .po file into .mo file and place to an appropriate folder. (e.g. languages/(domain_name)-pl.mo

In your Wordpress (plugin/theme I assume) code, you may call it like this,

for ($i=1;$i<15;$i++) {
  printf(_n("%d Comment", "%d Comments", $i, "(domain_name)"), $i);echo "<br />";
}
printf(_n("%d Comment", "%d Comments", 112, "(domain_name)"), 112);echo "<br />";

then of course set the WordPress's locale to Polish, in wp-config.php,

define ('WPLANG', 'pl');

you should see the results with correct plural forms.

Wolf
  • 9,679
  • 7
  • 62
  • 108
akky
  • 2,818
  • 21
  • 31
  • Your answer is in large part correct (except that you don't need for() - it will work with just `_n();` even if it theoretically supports only two plural forms). I found it out yesterday :) Thanks! – Atadj Aug 26 '12 at 15:11
  • 2
    The for loop is just to show the generated texts with more numbers. – akky Nov 12 '12 at 06:45
  • Could you explain `"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"` a bit more? Is this part of `babel.cfg` (in flask_babel)? Or the pot file? The po file? – Martin Thoma Aug 11 '19 at 19:54
  • 1
    It's in .po file to be converted to .mo file, then gettext uses the definition. – akky Aug 12 '19 at 22:57
0

I think I found a way to do what I want. POEdit application allows you to create multiple plural forms using the pattern you can specify in settings.

Translator have to code pattern on his own (see pattern for Polish in my question). I'm still researching that subject but if anyone has similar question then it's a good place to start: http://www.poedit.net/trac/wiki/Doc/PluralForms

Atadj
  • 7,050
  • 19
  • 69
  • 94