Open kauffj opened 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
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:
@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?
@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.
foo != 1 ? __('Plural foos') : __('One foo')
reduced to one string?@seanyesmunt please read/follow this thread
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.
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.)
I will try to answer the questions raised by @kauffj:
other
in the ICU model){
"You have %count% files": "{count, plural, one {You have {count} file.} other {You have {count} files.}}"
}
one
form and the other
form separately if the target language requires these 2 forms (this will need a try I think - never trust the docu of a tool) (the Transifex docu also doesn't mention how the zero
form is supported and it would really be a mess if it is not, as you need "You don't have a car." instead of "You have 0 cars.")const enNumPhotos = new IntlMessageFormat(
`
{count, plural, one {You have {count} file.} other {You have {count} files.}}
`,
'en-US'
);
return enNumPhotos.format({count: 1000});
I'm not a JS developer at all (I usually do Java backend stuff) but I'm sure this can be wrapped with a generic vararg function or fancy other stuff. Whether it is __n(...)
or whatever might be a decision to make after reading through the docu of the lib - as depending on lib, there might be some more to discover, like e.g. nested replacements.
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