DD 56: Weblate integration
##########################
Summary
=======
We are using `Weblate `__ to translate string in all
software components. Weblate should be able to read which strings needs to be
translated and return a translated version of the string for all the languages
supported.
Motivation
==========
Every development ecosystem has it's own i18n framework.
* Android has strings.xml
* Apple has Localizable.strings but it's deprecated
* We are using gettext PO as default
There is no standard file format in iOS, the current suggested format
is not supported by Weblate and looks like it's never going to be a
open documentation about it:
from `Apple developer forum `__
String Catalogs store an entire string table in a single JSON file,
even if there are a large number of keys and languages. If this ends
up presenting a problem (with Xcode's performance, for example), please send
some feedback our way.
As for the specifics of the JSON format itself, we have not published
documentation because it is primarily intended to be read/written by Xcode.
If you do end up writing your own parser for this format, please be aware
that Xcode reserves the right to change it.
What we are doing right now
---------------------------
How strings are generated:
*Android*:
Defines a key (like "send_deposit_amount_effective" or "amount_effective"),
this key has a default English translation in **strings.xml** and some other langs in **strings-{lang}.xml**.
*iOS*:
Uses the English text in the source code, or can also use a key.
It has just one file with translations, **Localizable.xcstrings**.
*SPA*:
It has the English string enclosed with i18n reference
and all those strings ends up in a file **src/i18n/strings.ts** which maps the English
sentence with a translated phrase. (the english sentence is used as a key)
For the integration in to weblate:
*Android*:
Weblate just takes **strings.xml** and **strings-{lang}.xml**, creates a list of all
strings to be translated and once you add new value for untranslated string or
change an existing one it modifies the correct file and commit with the new XML.
The project will automatically take this values.
*iOS*:
No integration has been found.
*SPA*:
The **strings.ts** file is not recognized by Weblate, so we generate **.po** files
which are supported by weblate. We have a script (pogen) that parses all the source code and
generate **.po** files, PO files are understood by Weblate and it will appear in the webapp
to be translated. Once the translator change some strings the PO files are updated with
the translations. When the changes are push into the repo, the developer can run a second
script (pogen) to sync the **.po** files with the **strings.ts**. Once in the **strings.ts** file the
app can show it in the UI.
Requirements
============
1. We should integrate weblate and iOS development
2. Translator should not translate 2 strings twice: if we can, we should reuse strings between apps
3. It should be clear wether we need to define a new string or add more context to the current strings
4. Stick to the `supported formats `__
Proposed Solution
=================
What we need to do to support iOS
---------------------------------
We should move into something more like what we are doing with the SPA since we don't have
full support for **Localizable.xcstrings** and this file is kind of the same as **strings.ts**
(one big json with the mappings).
That will mean:
1. dev code, code, code (adding new strings to be translated, removing some other strings)
2. dev run script to sync **Localizable.xcstrings** with **file-that-weblate-understands.po**
3. translators translate and push changes
4. dev run script to sync **file-that-weblate-understands.po** with **Localizable.xcstrings**
We only need to use our existing software **pogen** to create **po** files from the
**Localizable.xcstrings** which seems really easy. And then also update the
**Localizable.xcstrings** from the updated **po** files.
This will not stop us from using XLIFF exporting/importing.
What we need to do to reduce the work load in the translators side
------------------------------------------------------------------
We can split the problem in topics
Using the same i18n key between apps:
we should stick to DD53 Wallet Design and use this to define
which strings developers should use. If the string is defined
there then it should be used in the code. That will create a spec
for the 3 platforms and it should use the same key.
Using translation memory in weblate config:
from weblate documenantion, this can be used to automatically
share translations.
Using context keys for short keys:
Sometimes the words like "close" or "transfer" could have separated
meaning depending on the context. For that cases we have the
**msgctxt** (that is additional key in addition to the short
sentence). Only same sentence with same context are equivalent.
We can also add some more context, like a link to the screenshot
in the design document so we can trigger an alarm if an image in the
weblate translation is out of sync with an image in DD 53.
Using images in weblate:
We should keep DD 53 updated (with the screens and text) and add
information in the string sentence (like context) to point into
the right location.
What we need to do to reduce the work load in the translators side
------------------------------------------------------------------
1. devs and Weblate maintainers look into DD53 + Weblate maintainers take care of checks and keep the repos consistent and up-to-date
2. translators know the apps and strings very well and manage ambiguities
3. translators and reviewers take a look at:
* the context message ID / key
* string location in the source code
* "nearby strings"
* comments
* the history of string changes
4. devs and Weblate maintainers add screenshots to ambiguous strings
5. devs add context via msgctxt through the pogen script
Definition of Done
==================
* When iOS app has a complete semi-automated integration with weblate
* Adding msgctxt works for every platforms
Alternatives
============
Drawbacks
=========
Discussion / Q&A
================