Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support plural forms #46

Open
jobi opened this issue Jan 10, 2014 · 25 comments
Open

Support plural forms #46

jobi opened this issue Jan 10, 2014 · 25 comments

Comments

@jobi
Copy link

jobi commented Jan 10, 2014

A feature request, we would love it twine supported plural forms. Something like:

[delete_things]
    en:one = Delete this object?
    en:other = Delete these objects?

Android has support for plural forms in its string resources:

    <plurals
        name="plural_name">
        <item
            quantity=["zero" | "one" | "two" | "few" | "many" | "other"]
            >text_string</item>
    </plurals>

iOS could use Smartling

gettext also has support for plural forms

@scottdweber
Copy link

A very good idea! We have actually talked about this briefly, but have not taken it any further than casual discussion.

@yincrash
Copy link

The way I currently do plurals in twine is having a separate key for each plural, such as cool_things_one cool_things_other, then do

    <plurals
        name="cool_things">
        <item quantity="one">@string/cool_things_one</item>
        <item quantity="other">@string/cool_things_other</item>
    </plurals>

in a separate xml file in values/ that isn't managed by twine.

@jobi
Copy link
Author

jobi commented Jan 10, 2014

@yincrash that's a pretty good solution, but that means we need to maintain the list of keys in 2 places

@scelis
Copy link
Owner

scelis commented Apr 16, 2014

iOS and Mac actually support plurals natively as of 10.9 and iOS 7. You can read about this in the 10.9 Foundation Release Notes.

That said, plurals are tricky. One of the goals for Twine has been to maintain a simple feature set that all of the string file formats support. By fully supporting plural forms for Android, Mac, and iOS, we have to be careful that we don't prevent those strings from being written out to other formats like jQuery, gettext, etc.

I think the trick to implementing this feature properly is to use some sort of convention such that all strings can be written out to all formats. Maybe the twine syntax is modified as @jobi suggested. Plurals could be written out to formats that support it and those that don't will get multiple strings with well-defined suffixes like "delete_things__one", "delete_things__many", etc.

@pichirichi
Copy link
Contributor

This is a great idea @scelis , I like this approach.
This is even a challenge when sending strings for translation since most services don't support the plural format.

@scelis
Copy link
Owner

scelis commented Nov 30, 2015

The more I think about this feature, the more I think that the benefits do not outweigh the additional complexity.

@wujessica
Copy link

We had this problem consolidating Android and iOS translations for our app and we ended up implementing it in a project fork (with some convention ideas from here!). We'd be happy to send a PR if you think that would be useful.

@scelis
Copy link
Owner

scelis commented Aug 3, 2016

@wujessica Thanks for this! I am sure others may find it useful. It might be hard to merge into the main repo until we figure out how it functions with the other (non-iOS and Android) formatters.

@mvarshavsky
Copy link

@scelis - any way I can convince you to revisit your cost/benefit analysis above :) Any project will sooner or later encounter the need to pluralize. Having to maintain a separate per-platform file as @yincrash is doing it brings the problem twine is solving right back (granted, on a smaller scale). It seems like there must be a way to unlock this functionality for plural-aware formatters, while keeping it neutral for the rest (e.g., by convention only picking the first of key:qty occurrences). Also, if using up :blah just for this purpose it too greedy, a more generic scheme can be applied.

@scelis
Copy link
Owner

scelis commented Aug 16, 2017

@mvarshavsky Is there really great cost to not using plurals in your string files? We use plurals in our apps all the time and it requires just a few lines of code given our twine string file:

if numItems == 1 {
    label.string = localizedString("NumItemsSingular", numItems)
} else {
    label.string = localizedString("NumItemsPlural", numItems)
}

So yeah, I don't think that the amount of complexity this would add to twine would be worth it just to turn the above chunk of code into:

label.string = localizedString("NumItemsWithPlurals", numItems)

@mvarshavsky
Copy link

A lot of time it's three: no items / 1 item / n items - but that's besides the point; in my eyes it's just ugly superfluous code that detracts from readability. My belief is that placeholders/interpolation (which twine has) and ability to pluralize is something that all decent-sized projects eventually need and therefore all platforms will eventually evolve to support. I get you're trying to keep complexity out - but that choice pushes it to all consumers of your library :) Anyway, I'm not here to argue, it's your decision, just chiming in with another "+1" on the feature request. We have @wujessica's fork to fall back on. Appreciate all the work you've put into this!

@scottdweber
Copy link

Another consideration is that, while the following code works just fine for English and some other languages, there are many languages where such logic may not be appropriate (e.g. Korean, Chinese, Russian, etc.). These cases are where the platform's in-built plurals system helps you, and requires a more robust set of translations.

if numItems == 1 {
  // singular
} else {
  // plural
}

@scelis
Copy link
Owner

scelis commented Aug 16, 2017

Fair point. Once you need to support more than (0 | 1 | more) then it can get trickier. I would not be opposed to twine having decent plural support were a good PR to be submitted (which is why this feature request is still open), but it really is a huge undertaking and still not one that I am convinced is completely worth the effort.

The submitted PR would need to do the following:

  • Not break formatters that don't natively support plurals by using some sort of fallback convention.
  • Work for both reading and writing the localization files (both generate-localization-file and consume-localization-file)
  • Not make the twine file syntax significantly more complex.

@txaiwieser
Copy link

It would be awesome if the Android and iOS plural was merged to master.

@tobilarscheid
Copy link
Contributor

my team is also looking for this feature, why was the PR closed?

@greshilov
Copy link

We've implemented this functionality in our fork here:
https://github.com/mapsme/twine
Usage:

[placepage_summary_rating_description]
    en:one = Based on %d review
    en:other = Based on %d reviews
    ru:one = На основе %d отзыва
    ru:other = На основе %d отзывов
    ...

Plural strings works only for android and ios(see separate formatter apple-plural).
Possible plural modificators.
Hope this will be useful :)

@TomGranot
Copy link
Contributor

@greshilov - Coming late into the conversation, can you elaborate a bit on what you did? I think I'm going to use something similar in my setup.

@altagir
Copy link

altagir commented Mar 7, 2019

Hi @greshilov, I don't understand why you added apple-plural along with apple
can't they be merged?

We've implemented this functionality in our fork here:
https://github.com/mapsme/twine
Usage:

@greshilov
Copy link

@altagir if I'm not mistaken it was difficult to me to use same logic in one formatter for iOs plural/non plural strings. Unlike android, apple strings are actually generating to different files (.strings, .stringsdict).
This script here is using for generating all strings in mapsme, maybe helpful.

@Tomgs looks like I've lost your question :( If you still have any questions feel free to ask.

@altagir
Copy link

altagir commented Jul 9, 2019

@scelis , The fork from @greshilov works great for plural form (android and ios)
could it be merged ? this feature indicates "needs code".

@scelis
Copy link
Owner

scelis commented Jul 9, 2019

@altagir As far as I can tell, that code isn't really mergeable and was implemented as a one-off fork. I am still amenable to merging this feature into Twine proper, but my requirements from above still stand.

@altagir
Copy link

altagir commented Oct 15, 2019

hi @greshilov
on android translations, the character ' is not properly formatted in values/
A plural traduction of "don't ..." should be "don\'t..." else Android Studio cannot parse the xml
only happens with plural form
We use &apos; to handle correct output for ios and android

@timthelion
Copy link

@scelis Unfortunately your example:

if numItems == 1 {
    label.string = localizedString("NumItemsSingular", numItems)
} else {
    label.string = localizedString("NumItemsPlural", numItems)
}

doesn't work for all languages. For example in Czech genetive plural is different for0, 1, 2-4, and >4:

English: "1 banana"
Czech: "1 banán"

English: "2 bananas"
Czech: "2 banány"

English: "4 bananas"
Czech: "4 banány"

English: "5 bananas"
Czech: "5 banánů"

English: "100 bananas"
Czech: "100 banánů"

@scelis
Copy link
Owner

scelis commented Mar 7, 2023

@timthelion Yes, some languages are definitely more complicated. You should be able to take my 2 case example and extrapolate to N.

@timthelion
Copy link

I don't understand how you would do that. The only way that occurs to me to do this would be for the Czech translator would go and edit the code for every string that contains a plural and add a new string for greater than 4 for every language. That seems like a lot of work, and not all translators will know how to code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests