Use Crowdin for translations
We don't have any tooling for keeping track of which newly added english texts need to be translated into other languages. Nobody really knows how out of date our translations are, or how to find out. Instead of investing in such tooling ourselves, I suggest we look into using crowdin.com instead.
We recently started using Crowdin at work, and I was pleasantly surprised at what a nice and powerful platform this is. Basically you upload your english text file, and then contributors can swarm on typing in translations for various languages, all with a pretty nice web interface. There's a dashboard showing how many texts are left to be translated for each language, and also which texts have "quality issues" (an example being that the english text ends with a period, but the translation doesn't, and many others). And of course it can pre-translate things from Google Translate or DeepL automatically.
This requires that we have data files (json or yaml) instead of code for our translations, so we'd need to change our code a bit to serialize things to/from json or yaml. That doesn't sound very hard to me.
Crowdin is not cheap, but it has a free plan for open source projects which I think is very attractive.
Sounds good to me. Re: text files, I assume we would end up generating code from them with 'go generate', is that right?
Not really. For the english texts we'd need a script that marshals it to json so that we can upload it to crowdin (that json file doesn't have to be committed to git). For the translations we'd just download them as json files from crowdin, commit them to git, and then unmarshal them at runtime.
One of the many advantages of doing it this way is that developers no longer have to care about the translations at all. In commits such as 0df5cb1286a we had to touch all languages so that things compile again; this will no longer be necessary.
If we unmarshal at runtime, how does that work when we need to distribute a binary? This is something that I'd want to have baked into the binary which is why I assumed we'd use code generation to do that unmarshalling rather than handling at runtime.
I'm not tracking how the end-to-end flow works: if I want to add a new translated string in a PR, do I need to go into crowdin and update the translation there? Or do I update the json file locally and push it to crowdin? Or does CI do that for me?
Ah right, I forgot that we can't just add something to our Resources folder. 😄
In that case, yes, we'll need a go generate thing that generates code from the json files.
As for the workflow: developers would not usually be concerned with crowdin, they'd just edit the english translation struct in the code as today.
Then, occasionally somebody would run the script that generates json from the english struct, and upload that to crowdin. We could also look into automating this step on CI, I think it should be possible.
For the other direction, somebody would occasionally (e.g. just once right before a release is cut) download the translated json files and make a PR to commit them; at the same time the go generate would be run to convert them back into structs.
I'm happy to work on getting some (or all) of this going, but I don't think I'll have time for that before mid November.
Okay, sounds good!
An alternative to Crowdin is Weblate which is open source, free for open source projects and self-hostable if needed.
As translator I find it very user friendly and it has very nice GitHub/GitLab integration.
Anyway, choose according to the project's needs. I'm interested on Spanish so I'll be waiting for it.