Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#6255 closed defect (fixed)

Last preparation for the release

Reported by: Stan Owned by: Stan
Priority: Release Blocker Milestone: Alpha 25
Component: Internationalization & Localization Keywords:
Cc: Patch:

Description (last modified by Stan)

Fix translations

C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-lobby.pot - te: Found unknown sprintf `%(times)s`, `%(messages)s` in the translation which do not match any of the URLs in the template: `%(message)s`, `%(time)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - Different sprintf in singular and plural source strings for '<Message ('Could only be constructed once.', 'Could only be constructed %(limit)s times.') (flags: ['python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - id: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - ko: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - zh: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - zh_Hant_TW: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - Different sprintf in singular and plural source strings for '<Message ('Could only be trained once.', 'Could only be trained %(limit)s times.') (flags: ['python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - id: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - ko: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - zh: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - zh_Hant_TW: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - Different sprintf in singular and plural source strings for '<Message ('Could only be created once.', 'Could only be created %(limit)s times.') (flags: ['python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - id: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - ko: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - zh: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-ingame.pot - zh_Hant_TW: Found unknown sprintf `%(limit)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-simulation-other.pot - Different sprintf in singular and plural source strings for '<Message ('%(lastPlayer)s has won (last player alive).', '%(players)s and %(lastPlayer)s have won (last players alive).') (flags: ['python-format', 'javascript-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-simulation-other.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-simulation-other.pot - id: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-simulation-other.pot - ko: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-simulation-other.pot - ms: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-simulation-other.pot - zh: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-simulation-other.pot - zh_Hant_TW: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - Different sprintf in singular and plural source strings for '<Message ('%(lastPlayer)s has won (treasure collected).', '%(players)s and %(lastPlayer)s have won (treasure collected).') (flags: ['javascript-format', 'python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - id: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ko: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ms: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh_Hant_TW: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - Different sprintf in singular and plural source strings for '<Message ('%(lastPlayer)s has been defeated (treasure collected).', '%(players)s and %(lastPlayer)s have been defeated (treasure collected).') (flags: ['javascript-format', 'python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - id: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ko: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ms: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh_Hant_TW: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - Different sprintf in singular and plural source strings for '<Message ('%(lastPlayer)s has won (Capture the Relic).', '%(players)s and %(lastPlayer)s have won (Capture the Relic).') (flags: ['javascript-format', 'python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - eu: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - id: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ko: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh_Hant_TW: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - Different sprintf in singular and plural source strings for '<Message ('%(lastPlayer)s has been defeated (Capture the Relic).', '%(players)s and %(lastPlayer)s have been defeated (Capture the Relic).') (flags: ['javascript-format', 'python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - eu: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - id: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ko: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh_Hant_TW: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - Different sprintf in singular and plural source strings for '<Message ('%(lastPlayer)s has won (wonder victory).', '%(players)s and %(lastPlayer)s have won (wonder victory).') (flags: ['javascript-format', 'python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - id: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ko: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh_Hant_TW: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - Different sprintf in singular and plural source strings for '<Message ('%(lastPlayer)s has been defeated (wonder victory).', '%(players)s and %(lastPlayer)s have been defeated (wonder victory).') (flags: ['javascript-format', 'python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - eu: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - id: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - ko: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-maps.pot - zh_Hant_TW: Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template: `%(lastPlayer)s`
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - Different sprintf in singular and plural source strings for '<Message ('For the first minute, other players will stay neutral.', 'For the first %(min)s minutes, other players will stay neutral.') (flags: ['python-format'])>' in 'C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot'
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - gd: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - hu: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - id: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - ja: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - ko: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - ms: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - zh: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 
C:\Dev\0ad\binaries\data\mods\public\l10n\public-gui-other.pot - zh_Hant_TW: Found unknown sprintf `%(min)s` in the translation which do not match any of the URLs in the template: 

  • Update 0ad.nsi and build_archives.sh (could fix #6023 while at it)
  • Update the translators credits after the last pull

Change History (17)

comment:1 by Silier, 3 years ago

Component: Core engineInternationalization & Localization

comment:2 by Aziz Rahmad, 3 years ago

All the errors from ID (Indonesian) are from singular version of translations.

Indonesian language is generally has no difference between singular and plural form. However the English text contains some plural form using sprintf with the singular version not using sprintf e.g. singular once and plural %number times while Indonesian simply use '%number' for both, causing issues like:

Found unknown sprintf `%(players)s` in the translation which do not match any of the URLs in the template:

It seems in Indonesian translation there is no way to add singular form to this. I tried to add msgstr[0] and msgstr[1] for singular and plural and upload the .po file, but it seems Transifex rejects this as the change is not applied at all.

Anyone knows how to solve this?

comment:3 by MingyeWang, 3 years ago

zh speaker here. I am inclined to believe this is a bug in your localization pipeline (validation ... and the runtime if it does blow up). ngettext handles this thing just fine, as shown in https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html. Validation pipelines I've met usually only check against the English plural for this very reason.

I tried to add singular and plural and upload the .po file, but it seems Transifex rejects this as the change is not applied at all.

And correct, there *is* no way as long as the Plural-Forms in the header only says nplurals=1. I am strongly against changing that for... somewhat obvious reasons.

Last edited 3 years ago by MingyeWang (previous) (diff)

in reply to:  3 comment:4 by Aziz Rahmad, 3 years ago

Replying to MingyeWang:

zh speaker here. I am inclined to believe this is a bug in your localization pipeline (validation ... and the runtime if it does blow up). ngettext handles this thing just fine, as shown in https://www.gnu.org/software/gettext/manual/html_node/Plural-forms.html. Validation pipelines I've met usually only check against the English plural for this very reason.

I'm not familiar with the system. So is the problem within Transifex configs of my chosen language, or with 0 A.D.? Is it fixable?

comment:5 by Stan, 3 years ago

I think the issue is that you put the %(limit)s keyword in both translations on transifex (e.g both tabs) while it should only be in one. E.g.

Tab1

Could only be constructed once.', 
Ne peut être construit qu'une fois

Tab2

'Could only be constructed %(limit)s times.')
Ne peut être construit que %(limits)s fois

So the game expects a variable to replace while there is none. It usually errors out the other way around.

For the record we use a lib called tinygettext.

Last edited 3 years ago by Stan (previous) (diff)

in reply to:  5 comment:6 by Aziz Rahmad, 3 years ago

Replying to stanislas69:

I think the issue is that you put the %(limit)s keyword in both translations on transifex (e.g both tabs) while it should only be in one.

The problem is that since in Indonesian (id) there is no plural/singular tab, there is no option for me to add singular translation. I also tried downloading the .po file and add the translation manually, but after I upload it back, the change is not applied. Taiwanese Mandarin translator also get similar issue.

Is it possible for me to just upload the translation .po files directly as diff?

comment:7 by Stan, 3 years ago

Oh right. That's dumb...

It's not possible sadly, because it would get overwritten the next time we pull translations. I'm not sure whether it's a Transifex bug or not.

It seems it does not trigger errors in the game.

So for id at least it can be ignored, but I know it's not the case for gd.

We need an evolution of the linter script for those languages. (It's a bit too cautious it would seem)

Last edited 3 years ago by Stan (previous) (diff)

comment:8 by asterix, 3 years ago

Hi @stanislas69, can you please tell me, what is the problem with color, it is found under cs? How it should be corrected?

in reply to:  8 comment:9 by Silier, 3 years ago

Replying to asterix:

Hi @stanislas69, can you please tell me, what is the problem with color, it is found under cs? How it should be corrected?

Hi, please keep tags between [] excatly the same, no change in capitalisation nor spacing

comment:10 by asterix, 3 years ago

I believe I corrected most of them now but for the last one, I need a moderator or reviewer status.

in reply to:  10 comment:11 by Silier, 3 years ago

Replying to asterix:

I believe I corrected most of them now but for the last one, I need a moderator or reviewer status.

What is your name there? I unreviewed the the translation for time being

comment:12 by Stan, 3 years ago

I fixed most if not all the breaking ones, the rest are unfortunate but cannot be fixed right now. I'm waiting for tomorrow's pull.

comment:13 by Stan, 3 years ago

Description: modified (diff)

in reply to:  7 comment:14 by GunChleoc, 3 years ago

Replying to stanislas69:

Oh right. That's dumb...

It's not possible sadly, because it would get overwritten the next time we pull translations. I'm not sure whether it's a Transifex bug or not.

It seems it does not trigger errors in the game.

So for id at least it can be ignored, but I know it's not the case for gd.

We need an evolution of the linter script for those languages. (It's a bit too cautious it would seem)

The problem here is that the Gaelic plural rule for 1 also matches the number 11. So, if the English plural string makes a "special" case for the number 1, I have to ignore that special case and use the placeholder anyway, because otherwise any occurrences of 11 would be replaced by 1, which is clearly wrong. I see this mistake in plural markup of source strings a lot.

So the best solution here is to fix the source string rather than putting effort into changing the linter script. If you want to do some work on the linter script, including the source or target string would help translators to track down the string on Transifex.

comment:15 by Silier, 3 years ago

Honestly our plural strings should not contain additional tags but be just pluralized version of singular

comment:16 by Stan, 3 years ago

Owner: set to Stan
Resolution: fixed
Status: newclosed

In 25839:

Update translation credits.

  • Restore original language names, and keep an English fallback in case the font is missing for some languages.

Fixes: #6023
Fixes: #6255

in reply to:  15 comment:17 by GunChleoc, 3 years ago

Replying to Angen:

Honestly our plural strings should not contain additional tags but be just pluralized version of singular

Just wondering whether you are aware of the customizable Transifex placeholders? They might help here too. It's a bit hidden. You need to go to:

  1. Settings
  2. Workflow
  3. In the "Pre-translation" section, there's a link "translation checks" that will lead you to https://www.transifex.com/<organization>/settings/validations/
  4. Select the file format. A list of checks will expand from there.
  5. On the bottom of that list, there's another link "Set up custom placeholders"
  6. Add your variables

It doesn't seem to support regex though https://docs.transifex.com/translation-checks/setting-translation-checks

Note: See TracTickets for help on using tickets.