How to: Translate an application
Keep the texts of an Access application in any number of languages as files of the project, give each translator a package of their language in Excel, take all packages back in one step, and test the application in each language.
Prerequisites: WKL Office SDK 0.8 or later; WKL Forms Object Library 1.67 or later on the machines that run the
application (the object WklTexts).
Solution overview
- The texts are files of the project:
source/texts/neutral.jsonholds them in the language the application is written in, andsource/texts/<code>.jsonholds one translation each, for any language code (de.json,fr.json,pl.json…). - The build writes them into the table
USysWklTextsof the ACCDB and the ACCDE. At run timeWklTextsreturns each text in the language of the session; a key without a text in that language shows the neutral text, then the English one. The SDK is not needed at run time. - Every build reports missing translations, texts with other placeholders, keys the code asks for that have no text, and translations whose source text has changed since.
- Each translator gets a CSV package of one language that Excel opens directly; the packages come back in any order and are merged in one import.
Steps
Write the neutral texts in
source/texts/neutral.json, in the language you develop in. Every key needs a neutral text, because it is the fallback for every other language:{ "orders.saved": "{0} orders saved.", "orders.title": "Orders" }Name that language in the project file, so that it needs no file of its own and is not reported as untranslated:
<NeutralLanguage>en</NeutralLanguage>
Use the keys in the code through
WklTexts(see the documentation of WKL Forms Object Library, “Localize an application”):Dim texts As New WklTexts Me.Caption = texts.Text("orders.title") MsgBox texts.Text("orders.saved", count), vbInformation, texts.Text("wkl.information")Give each translator a package. One command per language:
wkl-office texts export Orders.acproj --language fr wkl-office texts export Orders.acproj --language it
Each command writes
texts.<code>.csvnext to the project file with the columnskey,source(the neutral text), the language, andreview. The translator fills only the language column in Excel and saves the file as CSV UTF-8. A row with text inreviewis a translation to check: the column shows the source text it was made from.Take all packages back at once, as soon as they arrive:
wkl-office texts import Orders.acproj texts.fr.csv texts.it.csvOnly the language columns are written. An empty cell and a missing row change nothing, so a translator who sends back half of the package loses nothing. One line per language names how many texts are new, changed, still untranslated and marked for review. Review and commit the files like any other source.
- Build and check.
wkl-office build Orders.acprojwrites the texts into the database and lists, as warnings, every key without a text in a language and every translation marked for review. Test in each language:
foreach ($language in 'en', 'fr', 'it') { wkl-office test Orders.acproj --language $language --work "test-results\$language" }
--languagesets the language of the session for the application texts and the WKL components, whatever language Office uses.
Result
The ACCDB and the ACCDE contain the table USysWklTexts with every text of every language. On a French Office the
application shows its French texts; a key without a French text shows the neutral text. A test run with
--language fr reports the same checks as on a French Office.
Remarks
- Two packages disagree. When two files give different texts for the same key and language, the import names each conflict, writes nothing and ends with exit code 2. Remove the wrong row or file and import again.
- The neutral text changed. The translations made from the earlier text are marked for review in
source/texts/review.<code>.json, and the next package shows that earlier text in the columnreview. A package translated from an outdated source text is taken over and marked the same way. The mark goes away when a translation of the current text comes back. - New keys come from the neutral texts. A package cannot add keys: a row whose key the application does not have is skipped with a warning.
- The whole set in one file.
texts exportwithout--languagewrites every language intotexts.csv, one column per language,neutralfirst.texts import --replace texts.csvtakes such a file as the whole set: a key missing in it is removed, and a language column that is empty in every row leaves its file as it is. - No neutral texts. A project with only
source/texts/en.jsonkeeps working: English is then the reference of the checks and of the packages. - Excel and separators. Excel saves CSV with the list separator of the regional settings, a comma or a semicolon;
texts importreads both. Save as “CSV UTF-8”: the plain “CSV” format of Excel loses č, š, ž and other letters outside the code page of Windows. - A file in the wrong place. A text file of a language outside
source/texts(for examplesource/fr.json) is not read;checkandbuildreport it as a warning. - Terminology.
source/texts/terms.<code>.jsonnames terms that should not be used, for example{ "podatkovna zbirka": [ "zbirka podatkov" ] }; every build reports a text that holds such a variant. - Edited in Access? The export never writes the table
USysWklTextsback: change texts in the files, not in the database. - Tests can find gaps.
WklTexts.Missinglists the keys that had no text in the language asked for; a test that checkstexts.Missing = ""fails on an incomplete translation.