olivierperez / o80-i18n

PHP i18n (internationalization) system.
Apache License 2.0
12 stars 5 forks source link

Plurals? #1

Open hermannschwaerzlerUIBK opened 9 years ago

hermannschwaerzlerUIBK commented 9 years ago

This is sort of a feature request. How are plurals handled in o80-i18n? I found nothing during a quick look around in the code. Are there any plans to implement this? Are you aware of how gettext handles this? https://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms

olivierperez commented 9 years ago

Hi, Plurals are not yet handled, and I think it's a lack. It might be nice if you could implement them.

What do you think about something like that:

// instance call
$i18n->plural($count, 'Section', 'SingleKey', 'PluralKey', $params...)
// shortcut call
__p($count, 'Section', 'SingleKey', 'PluralKey', $params...)
hermannschwaerzlerUIBK commented 9 years ago

Hi!

I can look into this but not earlier than in two or three weeks (as I am busy with other things until than).

Is there a reason why you suggest

$i18n->plural($count, 'Section', 'SingleKey', 'PluralKey', $params...)

This is IMO in two ways inconsistent with __() and __f():

  1. 'Section' is not the first argument
  2. $params... looks like it's not an array but a variable number of arguments.

So I would suggest this:

$i18n->plural('Section', 'SingleKey', 'PluralKey', $count, $params_arr)

What do you think?

olivierperez commented 9 years ago

I thought to put $count first in order to avoid the muddle between $count and $params_arr. But, it's true, a lot of i18n library put $count juste before $param_arr.

We could implement with your order :

// instance call
$i18n->plural('Section', 'SingleKey', 'PluralKey', $count, $params_arr)
// shortcut call
__p('Section', 'SingleKey', 'PluralKey', $count, $params...)

NB: Just like __f, for __p I would keep the $params.... The idea of __p is to create a shortcut for the instance method. It's not very short if you have to build an array for the fifth parameter.

I will not work on o80-i18n for now. The first of us who have time to implement it win!

PaulRieger commented 8 years ago

Why not move the pluralisation logic to the language file and the formatting function?

I really like the following approach: http://i18njs.com/#pluralisation Source code: http://i18njs.com/js/i18n.js

Basically, this function is responsible for selecting the correct pluralization:

if (value instanceof Array || value.length) {
    for (_i = 0, _len = value.length; _i < _len; _i++) {
        triple = value[_i];
        if ((num >= triple[0] || triple[0] === null) && (num <= triple[1] || triple[1] === null)) {
            result = this.applyFormatting(triple[2].replace("-%n", String(-num)), num, formatting);
            return this.applyFormatting(result.replace("%n", String(num)), num, formatting);
        }
    }
}

The only challenge I see with this approach is the usage of multiple placeholders that need pluralization.

What do you think about this approach?

tommyknocker commented 8 years ago

That's simpler https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals than your suggestion espesially for translators. The only thing your must to provide with your language file is number of the rule.

Here is an example:

English is 1st rule, Russian is 7th rule.

Only two forms in English:

{
    "Generic":  {
        "apples": "apple;apples"
    }
}

But three forms in Russian:

{
    "Generic": {
        "apples": "яблоко;яблока;яблок"
    }
}
tommyknocker commented 8 years ago

Pull request with __p() and Plural Rules support: https://github.com/olivierperez/o80-i18n/pull/2

PaulRieger commented 8 years ago

Ok, but how is that going to work for complex sentences:

English:

%s says, that it is going to rain for %d days.

German:

%s sagt, dass es %d Tage lang regnen wird.

For d = 1, the correct translations are:

John says, that it is going to rain for one day.
John sagt, dass es einen Tag lang regnen wird.

For d = 2, the correct translations are:

John says, that it is going to rain for 2 days.
John sagt, dass es 2 Tage lang regnen wird.

In my opinion, it's a lot easier to do these kind of translations with the approach that I've suggested.

tommyknocker commented 8 years ago

Imho, the correct translation in the first example should be:

John says, that it is going to rain for 1 day.
John says, that it is going to rain for 2 days.
John says, that it is going to rain for 13 days.
etc.

So Mozilla plural forms should be fine here and much easy to translate by non-programmer translator. But in more complex way with changing first number to string ("1" to "one") your variant is better maybe.