lbryio / lbry-desktop

A browser and wallet for LBRY, the decentralized, user-controlled content marketplace.
https://lbry.tech
MIT License
3.57k stars 414 forks source link

Support proper i18n pluralization #3440

Open kauffj opened 4 years ago

kauffj commented 4 years ago

We should use __n for numeric messages to support unlimited, language-specific messages.

More: https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html

marko-lorentz commented 4 years ago

I saw that the number of places where if-statements are used in the code to pick the correct plural form is increasing. Having if in every piece of source code is a mess that makes it less readable and introduces new errors. It also assumes that the developer understands the plural rules of all language as he must add the correct if-blocks (for Russian this would be 4, for Arabic it's up to 6). All this should go to a central function that does the desired replacements automatically. In the source code, only a single method call should remain.

I would recommend to adapt the ICU recommendations for plural and gender oriented message formatting as far as possible.

More information can be found here

Suisse00 commented 4 years ago

WARNING: No real experience with i18 and languages I work with only contains one plural form

On the code side it could be only one method with ONE specific translation key that, behind the scene, change according with the number.

Eg. __n('You have %n messages', n)

TLDR: Behind the scene it will look for the key 'You have %n messages' + [${n}] I added a kind of [n] at the end just to recognise such string, could append only the number

If n is 1 then it will look for 'You have %n messages[1]', if this is 3 'You have %n messages[3]', ...

Downsides:

marko-lorentz commented 4 years ago

@Suisse00 The downsides you mention are nearly completely covered by the ICU model:

Would it make sense when I provide an example in source code?

kauffj commented 4 years ago

@marko-lorentz thanks for your message. I get the impression you know more about i18n than anyone at @lbryio currently :grin:, but we're always happy to learn from those that know more than us.

  1. Can you clarify what the syntax is when there is no variable in the message? How is foo != 1 ? __('Plural foos') : __('One foo') reduced to one string?
  2. To reduce to one string in code, I assume this would also require us to begin putting some English strings into Transifex. Is that correct? Right now we rely on the English message passing through for English strings, and do not maintain or access a translations file.
kauffj commented 4 years ago

@seanyesmunt please read/follow this thread

infinite-persistence commented 4 years ago

For number 2, doing that would also solve the "can't reuse the same string in different locations for my language" problem that few have reported (https://github.com/lbryio/lbry-desktop/pull/4340#issuecomment-641476349). I believe that if more translators verify the context of the strings, we'll get more reports of this issue.

marko-lorentz commented 4 years ago

Sidenote concerning the use of entire strings in code: The "have a complete string in the code"-approach has some charm (like: the software will work out of the box - even without any translations - and of course the explicit in-context listing of all replacement parameters with (hopefully) good names in an example phrase to ease understanding for the translators). But it has also some well known disadvantages (like: fixing typos will ping all translators if Transifex is aware of what you do and you will end up having duplicates or close duplicates that cannot easily be kept "similar" by the translators). My conclusion at the moment: I don't dare to propose a solution for this as you can do it one way or the other. It must make sense to those who work with the code and do tests on a daily base. Maybe it might be worth a try to do both: Have a set constants that can be reused as well as plain strings. The decision, when to offer a publicly visible constant like 'TERM_FOLLOWER' instead of a private plain string might be challenging.

(Translators should at least have a short look at the actual places where their texts are used. And it feels strange that I wasn't able to find good support for hyperlinks (e.g. to the correct place in the lbry.tv UI or to the source code) and screenshots in Transifex - something that is quite common in other translation support systems. Maybe I'm just to stupid to find it.)

marko-lorentz commented 4 years ago

I will try to answer the questions raised by @kauffj: