I thought I'd just write a bit about how I handle localisation across site and apps, in case other people find it interesting, and if there is sufficient interest, I might be able to put some of our tools on Github.
The main app I write is a client for a social network site that I run. That site is available in four languages at present: English, German, French and Spanish; to manage that we use the Smarty templating engine, which allows us to take most of the text out of the template files and put it in langauge config files. So, a template might say something like
and an accompanying langauge file will contain a line that says
That works for one language, but Smarty also allows sections, denoted using square brackets, like in PHP, so the template can say
and then the language file can say
This works well for the web, and when we add a new page, we can send the original version off to a translator and they can send me back a new version. However, especially using volunteers, that slows things down a bit, as I don't like to launch new features unless they're available in all our supported languages. We've been experimenting with machine translation, using DeepL.com which most people feel gives better results than Google.
So, I've now built a php script called deepler that will take the names of text files and run them through DeepL to create a multilingual version. So if I want quite translations, I just type
to generate the language file. It can then be revised by volunteers if there are any serious problems, but in the meantime we have something that should at least be passable.
And so to B4X. I looked at the Localizator tools, and they do the job, but personally I found the idea of using a spreadsheet unwieldy, and it would mean that for our volunteers, they'd have to do things differently depending on whether they were working on translations for the website, or for the apps. So, instead, I've build a script that will take the language files created by the deepler tool, and compile them into an sqlite database; the format is not quite the same as Erel's, but it would a simple fix to make it so.
So, I can create the text files for the app in exactly the same way, run them through the deepler script to get machine translations, and then compile them to a translations.db file with the command
Since we're dealing with German, there are an awful lot of long words (it's good to have a 'less formal' option on DeepL, but I'd really love one for "use short words"), so I've also created a tool to help flag those up; it internally renders an image of the text using a TTF file and compares the length to the base langauge, which is set to English. So I can type
and get back a result that flags up anything more than 10% longer than the English:
So, I won't claim this is the most streamlined process ever, but it does work for me; it means my volunteer translators only have to work in one way, regardless of whether it's app or website, and we can get things done fast (it's also possible to use the free version of the DeepL API, too, with a small tweak), plus flag up things that might be too big for on-screen labels or buttons.
If there's any interest, I can tidy the code up a bit and pop it on Github somewhere, though I expect it's probably only really useful if you want to have a common translation process across your web site and your apps.
Nigel
The main app I write is a client for a social network site that I run. That site is available in four languages at present: English, German, French and Spanish; to manage that we use the Smarty templating engine, which allows us to take most of the text out of the template files and put it in langauge config files. So, a template might say something like
HTML:
{config_load file='account.txt'}
<head>
<title>{#pageTitle#}</title>
</head>
and an accompanying langauge file will contain a line that says
B4X:
pageTitle = Account settings
That works for one language, but Smarty also allows sections, denoted using square brackets, like in PHP, so the template can say
HTML:
{config_load file='account.txt' section=$language}
and then the language file can say
B4X:
[en]
pageTitle = Account settings
[de]
pageTitle = Kontoeinstellungen
This works well for the web, and when we add a new page, we can send the original version off to a translator and they can send me back a new version. However, especially using volunteers, that slows things down a bit, as I don't like to launch new features unless they're available in all our supported languages. We've been experimenting with machine translation, using DeepL.com which most people feel gives better results than Google.
So, I've now built a php script called deepler that will take the names of text files and run them through DeepL to create a multilingual version. So if I want quite translations, I just type
B4X:
php deepler.php account.txt
to generate the language file. It can then be revised by volunteers if there are any serious problems, but in the meantime we have something that should at least be passable.
And so to B4X. I looked at the Localizator tools, and they do the job, but personally I found the idea of using a spreadsheet unwieldy, and it would mean that for our volunteers, they'd have to do things differently depending on whether they were working on translations for the website, or for the apps. So, instead, I've build a script that will take the language files created by the deepler tool, and compile them into an sqlite database; the format is not quite the same as Erel's, but it would a simple fix to make it so.
So, I can create the text files for the app in exactly the same way, run them through the deepler script to get machine translations, and then compile them to a translations.db file with the command
B4X:
php compile-translations.php NAV_account.txt NAV_android.txt NAV_app_tour.txt
Since we're dealing with German, there are an awful lot of long words (it's good to have a 'less formal' option on DeepL, but I'd really love one for "use short words"), so I've also created a tool to help flag those up; it internally renders an image of the text using a TTF file and compares the length to the base langauge, which is set to English. So I can type
B4X:
php measure-texts.php NAV_tagopts.txt
and get back a result that flags up anything more than 10% longer than the English:
B4X:
Language set = en de fr es
Processing NAV_tagopts.txt
Checking line lengths...
to_phone: de exceeds base by 17.6%
en: Phone
de: Telefon
to_email: de exceeds base by 15.9%
en: Email
de: E-Mail
So, I won't claim this is the most streamlined process ever, but it does work for me; it means my volunteer translators only have to work in one way, regardless of whether it's app or website, and we can get things done fast (it's also possible to use the free version of the DeepL API, too, with a small tweak), plus flag up things that might be too big for on-screen labels or buttons.
If there's any interest, I can tidy the code up a bit and pop it on Github somewhere, though I expect it's probably only really useful if you want to have a common translation process across your web site and your apps.
Nigel