Download & Extend

Clarify documentation for format_plural()

Project:Drupal core
Version:7.x-dev
Component:documentation
Category:bug report
Priority:normal
Assigned:Unassigned
Status:closed (works as designed)

Issue Summary

There are several languages for which 1 is not the only singular number:
#170334: format_plural() correction on singulars
But it seems like there's a lot of misinformation regarding that, so lots of projects are putting 1 in the singular strings when it's not actually the best idea.

This issue is just to take out the "Do not use @count in the singular string." from the PHPdoc for format_plural(), but there may be other places to raise awareness about it.

Comments

#1

Category:bug report» task

http://api.drupal.org/api/function/format_plural/7

AttachmentSizeStatusTest resultOperations
issue-384866.patch926 bytesIdlePassed: 11308 passes, 0 fails, 0 exceptionsView details | Re-test

#2

Component:language system» documentation
Status:active» needs review

#4

We got a bug report in privatemst to _not_ use @count if it would be the same string, because it can't be translated differently then: #373092-12: privatemsg_title_callback should use format_plural

Just FYI...

#5

Status:needs review» closed (won't fix)

No. In the signature of format_plural(), $singular and $plural are the *English* forms. You use @count or "1" in the $singular, as you want. It doesn't matter at all for translations.

This is because the plural string "$singular-$plural" is translated into n-plural forms (where n is language dependent), that are no direct translations of either $singular or $plural.

Edit: I was wrong here: you *have to* use "1", not "@count" in the singular form.

#6

Status:closed (won't fix)» active

Sorry to revive this thread, but I was hoping to get some clarification on this. If, for example, I input the singular string as "1 new message" and translate that into the French "1 nouveau message", I run into a problem when the singular form is used in the case that the count is zero—I will see "1 nouveau message".

I suppose that the fix for this is to use @count in the French translation of the singular string? If this is the case, then it is not very obvious or intuitive, and should maybe be documented somewhere.

#7

Title:@count should be used in singular strings, and the PHPdoc for format_plural() should say so» format_plural() and locale_get_plural() are not general enough for all languages
Component:documentation» language system
Category:task» bug report

This is a real problem, actually.

The way that format_plural() works is that it queries locale_get_plural() to find out whether the number $count is considered to be singular or plural for the language being used, and then it uses either the singular or plural format.

However, this will really not work for all languages. For instance, in Russian, there are different words used for 1, 2-4, and 5 or more of something. See
http://en.wikipedia.org/wiki/Grammatical_number
http://en.wikipedia.org/wiki/Dual_%28grammatical_number%29#The_dual_in_t...

So the whole idea of having singular/plural just doesn't apply to all languages... This is a code/locale issue, not documentation. Although if we stick to the function continuing to behave as it currently does, I agree that the documentation and examples for the singular string should contain @count rather than 1.

#8

Title:format_plural() and locale_get_plural() are not general enough for all languages» Clarify documentation for format_plural()
Component:language system» documentation
Category:bug report» task

Again, no, there is no bug here.

The way that format_plural() works is that it queries locale_get_plural() to find out the number of the plural form of $count for the language being used. Each language can have more then 2 plural forms, and the formula is language-specific.

The two forms in the signature of format_plural() are *English* forms. In English the first plural form is only used for $count = 1 (and as such, it makes sense to have the 1 in $singular), the second plural form is used for all other values of $count.

Back to documentation.

#9

Ummmm... Really?

I'm just looking at the function code at http://api.drupal.org/api/function/format_plural/7

If $count is 1, it just does t($singular), which seems to be non-controversial.

Otherwise, it is calling locale_get_plural($count) to get an index. But then it is just calling either t($singular) if the return value is 0, or t($plural) if the return value is 1, or t($plural) with @count replaced with @count[5], e.g., if locale_get_plural() returns the number 5.

I don't see how that is allowing translators to translate "1 new message"/"@count new messages" from English into "0 nouveau message"/"1 nouveau message"/"@count nouveax messages" for French (and pardon me if my French is not quite correct)? Or for Russian into the equivalent of "0 newzeroform messagezeroform"/"1 newoneform messageoneform"/"2-4 newsmallform messaagesmallform"/"5+ newsmallform messagesmallform"?

Please enlighten... and how should we reform the doc anyway?

#10

Yeah, this is not making sense to me. If we're always inputting 2 English strings, how do we get 3+ translated strings out? And if we're advising developers to include the number 1 in the singular form string, shouldn't it ONLY be used when $count is 1? All other cases should use one of multiple plural form strings.

#11

The confusion comes from the way the plural forms are stored in _locale_import_one_string():

  • $singular (aka 1 comment) is the source string of the plural form 0
  • $plural (aka @count comments) is the source string of the plural form 1
  • preg_replace('/(@count)/', "\\1[$key]", $plural) (aka @count[2] comments, @count[3] comments, @count[4] comments, ...) are the source strings of the plural forms 2, 3, 4, etc.

#12

Damien: Thanks for taking the time to patiently explain this... I think I get it now.

I'm getting from this that there's some way for the French translation team to set up that return values for locale_get_plural() could bet set up for French so that they were 0 for singular, 1+ for plural, and 2 coding for zero. And then they can make it so that "@count[2] new messages" is translated into "0 nouveau message".

Similarly, the Russian team can set up their locale_get_plural() return values so that 0 means 1 item, 1 means 2-4 items, 2 means 0 items, and 3 means 5+ items, and translate "@count[2] new messages" to the equivalent of "0 new messages", and "@count[3] new messages" to the equivalent of "5+ new messages".

In which case, do we even have a documentation issue for the format_plural() function? It looks like what it is currently saying is correct.

Maybe all that needs to be documented is how to set up a locale correctly with these plural codes for a language, and if French is not currently set up as described above, maybe it's a bug in the French locale/translation setup?

#13

I agree that in French there should be a separate plural form for the case where $count = 0. The docs specifically state 'Do not use @count in the singular string.', meaning that the singular string should specifically contain the number 1 and is only useful in the case that $count = 1. Related issue: #30876: Bug with plural forms.

Also, we need an easy way to explain to translators what a string like '@count[2] new messages' represents. It's not intuitive to know that it means "'0 new messages', in French".

#14

Category:task» bug report
Status:active» closed (works as designed)

The French plural formula is nplurals=2; plural=(n>1), which is exactly what it is supposed to be (form 0 is $count = 0 or 1, form 1 is everything else).

Also note that translators *never see* the @count[2] new messages. This is only how Drupal internally (and artificially) stores the source strings of plural forms.

Back to by design, there is absolutely nothing wrong here that I can see.

#15

The French plural formula is nplurals=2; plural=(n>1), which is exactly what it is supposed to be (form 0 is $count = 0 or 1, form 1 is everything else).

In that case, shouldn't the PHPdocs change?

$singular The string for the singular case. Please make sure it is clear this is singular, to ease translation (e.g. use "1 new comment" instead of "1 new"). Do not use @count in the singular string.

If the singular form is going to be used in more than one case, then the string SHOULD use @count. We can't expect translators to just know that "sometimes, the number '1' in strings should be replaced by '@count'". :S

Also note that translators *never see* the @count[2] new messages. This is only how Drupal internally (and artificially) stores the source strings of plural forms.

Then how are these translations submitted?

#16

Status:closed (works as designed)» active

No one answered that last comment, because the issue had been closed as "by design". I'm confused -- is there an issue or not?

#18

Status:active» closed (works as designed)

The reason for putting 1 in the English singular strings was mentioned way back in #4. The singular and plural forms have to be different in order for them to be translated at all. Usually this isn't a problem because of verb conjugation, but it can play havoc with abbreviations like "1 min" vs. "@count min".

French translators (and other languages that use singular forms for other numbers) just need to know to use @count. If there's a documentation issue, that's where it is, not with format_plural().

#19

Nothing wrong here.

#20

Could someone answer the question in #15, I don't understand that either:

Also note that translators *never see* the @count[2] new messages. This is only how Drupal internally (and artificially) stores the source strings of plural forms.

Then how are these translations submitted?

#21

on admin/build/translate/search
search for @count[2]

nobody click here