Open akirk opened 7 years ago
Just an update: we're waiting on some GlotPress changes so it can handle stringsDict
files before we do anything about this on our side.
More than supporting the specific format, I'm not sure if GlotPress can handle multiple files. @akirk if we were to import a file with just the plurals in a format that GlotPress understands, wouldn't that remove all the other originals from the project?
One idea that's been growing on me today is to forget about adding new importers to GlotPress and handling everything on our side, merging all our strings into a big PO file, which GlotPress can understand perfectly.
Then we'd export each translation as a PO file as well, and use that and the original strings/stringsdict/xliff files generated by Xcode to generate the translated files that Xcode wants.
Also, neither genstrings
or xcodebuild -exportLocalizations
seem to be picking up plurals automatically, so we'd need to manually manage them or build a tool to extract them from the code.
Some candidates for plural support (there might be more):
iconv -f utf-16le -t utf-8 WordPress/Resources/en.lproj/Localizable.strings | grep '^".*%[^"]*s\b'
"%@ comments" = "%@ comments";
"%@ days" = "%@ days";
"%@ followers" = "%@ followers";
"%@ levels" = "%@ levels";
"%@ links" = "%@ links";
"%@ of views" = "%@ of views";
"%@ posts on %@" = "%1$@ posts on %2$@";
"%@ views" = "%@ views";
"%@ views per visitor" = "%@ views per visitor";
"%@ visitors" = "%@ visitors";
"%@ was reconnected." = "%@ was reconnected.";
"%d accounts" = "%d accounts";
"%d days" = "%d days";
"%d hours" = "%d hours";
"%d months" = "%d months";
"%d pixels" = "%d pixels";
"%d years" = "%d years";
"%i menu area in this theme" = "%i menu area in this theme";
"%i menu areas in this theme" = "%i menu areas in this theme";
"%i menus available" = "%i menus available";
More than supporting the specific format, I'm not sure if GlotPress can handle multiple files. @akirk if we were to import a file with just the plurals in a format that GlotPress understands, wouldn't that remove all the other originals from the project?
Correct but not set in stone, this can be easily arranged that an imported file augments the existing strings and/or to import two files in one go. It could be done with a GlotPress plugin.
One idea that's been growing on me today is to forget about adding new importers to GlotPress and handling everything on our side, merging all our strings into a big PO file, which GlotPress can understand perfectly.
I like that a lot. A problem with generating the stringsdict
on GlotPress side is that the PO way of defining plurals is with an "nplurals" formula, while stringsdict
uses notions of one
, some
, few
, many
that would need to me mapped to the appriopriate plurals in each language which would require a whole new dependency of something like CLDR. This could be avoided with your approach.
Progress so far:
It looks like xgettext has some support for Objective-C (which also works on Swift). Unfortunately it doesn't pick up the existing translation comments. I decided to leave string extraction to genstrings
for now and focus on plurals for the moment.
I have this new macro:
#define NSLocalizedStringPlural(singular, plural, number) NSLocalizedString(singular, @"")
What we can do with this, is to have genstrings
skip the plurals, then do a second pass with xgettext
to extract those. We'd have to specify translation comments gettext-style though:
// Translators: Message informing the user that all of their sites are currently hidden
self.noResultsView.titleText = NSLocalizedStringPlural(@"You have 1 hidden WordPress site.", @"You have %lu hidden WordPress sites.", count);
// Translators: Prompt asking user to make sites visible in order to use them in the app
self.noResultsView.messageText = NSLocalizedStringPlural(@"To manage it here, set it to visible.", @"To manage them here, set them to visible.", count);
And we can have xgettext
generate a proper PO with that:
$ xgettext WordPress/Classes/ViewRelated/Blog/BlogListViewController.m -L ObjectiveC --from-code=utf-8 -o - -k -kNSLocalizedStringPlural:1,2 -cTranslators:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-02-24 17:24+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#. Translators: Message informing the user that all of their sites are currently hidden
#: WordPress/Classes/ViewRelated/Blog/BlogListViewController.m:269
#, c-format
msgid "You have 1 hidden WordPress site."
msgid_plural "You have %lu hidden WordPress sites."
msgstr[0] ""
msgstr[1] ""
#. Translators: Prompt asking user to make sites visible in order to use them in the app
#: WordPress/Classes/ViewRelated/Blog/BlogListViewController.m:271
msgid "To manage it here, set it to visible."
msgid_plural "To manage them here, set them to visible."
msgstr[0] ""
msgstr[1] ""
The next step would be to be able to convert that PO into a .stringsdict
. This project might help with converting the plural forms from gettext to stringsdict, but we still need to figure out the right way to extract NSStringFormatValueTypeKey
(i.e. if the format specifier is %d
, %lu
, %@
,...).
Once we have that, I believe the rest will be easy, as the gettext tools to work with PO files are really good and support merging and comparing files really well. They even support reading and writing .strings
files!
FYI work has commenced in https://github.com/GlotPress/GlotPress-WP/issues/666 to address that difference in plural definition which will allow the implementation of thr stringsdict
format.
This issue has been marked as stale and will be automatically closed. This happened because:
However, discussion is still welcome! If the issue is still valid, please leave a comment with a brief explanation so the issue can be reopened.
This issue has been marked as stale because:
[Pri] Blocker
, [Pri] High
, or good first issue
.Please comment with an update if you believe this issue is still valid or if it can be closed. This issue will also be reviewed for validity and priority (cc @designsimply).
@akirk just checking in on this issue, I noticed https://github.com/GlotPress/GlotPress-WP/issues/666 is still open, is that a blocker for this issue in the iOS app?
Correct, unfortunately GlotPress development seems to have halted for now. I'll see if we can get it moving again.
This issue has been marked as stale because:
[Pri] Blocker
, [Pri] High
, or good first issue
.Please comment with an update if you believe this issue is still valid or if it can be closed. This issue will also be reviewed for validity and priority during regularly scheduled triage sessions.
Still valid! @akirk may I check in with you again about the status of https://github.com/GlotPress/GlotPress-WP/issues/666? I'm asking because this issue is stale, not because it's prioritized. So an update to say it's still in progress is acceptable and that will make it so we put it on hold again but check back in on it in a year if it goes stale again. 🙂
This issue has been marked as stale because:
[Pri] Blocker
, [Pri] High
, or good first issue
.Please comment with an update if you believe this issue is still valid or if it can be closed. This issue will also be reviewed for validity and priority during regularly scheduled triage sessions.
@frosty In #6208 you introduced the construct:
Unfortunately this cannot be translated properly because some languages don't just have a different plural for
count != 1
(for example Russian, they use one form for 1, 21, 31; another one for 2, 3, 4; and yet another one for 5, 6, …). Please see Handling Noun Plurals and Units of Measurement in the iOS docs on how this can be done universally. Thanks!