How to specify ordered variables in gettext .po files?
Asked Answered
W

2

2

I have a multi-lingual site that uses Zend_Translate PHP arrays to handle the translations. It works fine, but I'm trying to convert to using gettext since that offers extra features.

However, I haven't yet discovered the gettext equivalent of a feature that I liked in PHP array translations: n$ position specifier (example #4 of PHP sprintf).

I found a good example of what I want (notice how the order of the variables is different in English and Chinese):

#: wp-admin/upload.php:96
#, php-format
msgid "File %1$s of type %2$s is not allowed."
msgstr "类型为%2$s的文件%1$s不允许被上传。"

But I haven't gotten it working for me. My en/messages.po file has this:

#, php-format
msgid "Earn X cash"
msgstr "%1$sEarn 1-30%% cash back%2$s, get money-saving coupons, and find the best price on every purchase at %3$s2,500+ stores%4$s."

and the PHP is this (which had worked for the array style of translations, and I don't think it is supposed to change):

<?php echo $this->translate('Earn X cash', '<span class="earnCashBack">', '</span>', '<a href="/stores" class="numStores">', '</a>'); ?>

The HTML comes out wrong, like this:

$sEarn 1-30% cash back$s, get money-saving coupons, and find the best price on every purchase at $s2,500+ stores$s.

How must I edit the .po file for this to work? Or should I not be using php-mo for compiling the .po into the .mo file?

Withers answered 20/12, 2012 at 20:27 Comment(1)
Here is a hint I found that may help: php.net/manual/en/function.sprintf.php#25243Withers
W
1

My .po and .mo files worked (and my webpage looks good) after I tried commenting out this line of php-mo.php:

$x = str_replace('$', '\\$', $x);

I'm actually not sure why that line was there at all, but removing it makes me nervous that I might be introducing bugs that I haven't discovered yet. But at least it fixed the problems that I could see!

Withers answered 20/12, 2012 at 20:58 Comment(0)
B
0

As a general guideline: You should avoid mixing multiple variables with gettext.

I will explain why.

First, this "limitation" is because there are languages that have more than 2 plural forms (6 for example).

Now imagine you mix 2 variables or more, each with his own 6 plural forms (1 file, 2 files, 10 fileses, 100 filec, filares 1000..).

You will force the translators team to create so many combinations that their job will become unpractical. Many programmers are not aware of this characteristic of various languages and mix more than one parameter with text in their implementations, making the translation for such languages, an IMPOSSIBLE task. This is simply because, most of us, we are using English and we can not imagine that our message maybe translated someday in such complex languages.

Second, now imagine you combine plural forms with grammatical GENDER. Many languages have different forms depending on the gender of the variable you are replacing with.

Gettext found an elegant and simple solution to this problem by recommending to use only one variable per string that needs to be translated. If you have more than one variables into a text that need to be translated simply split the phrase in separate strings containing each variable!

The "magic" of translating plural-terms with gettext is done using gettext C plural formulas.

What is gettext plural formula?

The information about the plural form selection is stored in the header entry of the PO file (the one with the empty msgid string). The plural form information for english language looks like this:

"Plural-Forms: nplurals=2; plural=n == 1 ? 0 : 1\n;"

Now let's take a look on Polish language formula:

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

The only possible way to interpret this formula is to have only one variable 'n' affecting the string translation.

Conclusion: any translation implementation that allow you to mix multiple variables together is a NAIVE implementation created by a English native speaker programmer that does not understand the problems posed by translating in every language on this planet. Gettext implemented the right way to do it and you should not mimic the behavior of other broken translation libraries.

Bergh answered 28/8, 2022 at 14:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.