I18N with Lazarus
It's pretty difficult to find information about how to write a multi-lingual application with Lazarus. I've been through this and I hope that this article helps others to get on the right way. I'm not 100% sure the way I found is the right way but at least it works great for me. So it can't be totally wrong.
The first source of information I found about I18N in Lazarus was this Wiki article. So I activated I18N support in the project settings, copied the generated po-file, translated it and used the code mentioned in the Wiki article but after solving some hard to find problems I ended up with translated resource strings but the texts in the forms were still untranslated. This is pretty useless because most of the texts I want to have translated are in the forms and not in resource strings.
After some more investigations I found this bug report which mentions a unit named DefaultTranslator. I read the source code of it to understand how it works and then tried it out and it was amazing how good it works. So here are my few steps to a working I18N solution with Lazarus:
- Activate I18N support in the project settings. Use
languages/enas PO output directory. - Add the unit DefaultTranslator to the uses section of your LPR file.
- Write your application and make sure that all strings which are used manually in the units (Like messages passed to a message dialog and stuff like this) are implemented as resource strings as mentioned in the Wiki article. Lazarus will automatically update the file
languages/en/projectName.powhile you write your application. All resource strings and all messages used in forms (like captions and stuff like that) will end up in this po-file. - When you are finished with your application then copy the created po-file into the directory
languages/de(de is the language code for German). - Install Poedit and load the
languages/de/projectName.pofile into it. - Translate all the messages and save the translation. This will automatically create a mo-file.
That's all. If you now start your application on a German Windows then the application starts with German text resources. If you don't have a German Windows then you can try setting the LANG environment variable to de or simply use the command line argument --lang de to test it.
Update (2009-01-11)
There is a small bug in DefaultTranslator unit: Messages in a message context are not translated correctly. I have reported the bug and provided a patch here. You can fix the bug yourself in your Lazarus installation: Just open the DefaultTranslator unit, add the lines mentioned in the patch, add the Forms unit to the uses section and then rebuild Lazarus with the corresponding menu item in the Tools menu.
Lazarus Wiki mention about this solution and its disadvantages:
"the disadvantage is that you'll have to keep around both the .mo files for the DefaultTranslator unit and the .po files for TranslateUnitResourceStrings"
This method also have advantages:
"If you use DefaultTranslator, it will try to automatically detect the language based on the LANG environment variable (overridable using the --lang command line switch), then look in these places for the translation (LANG stands for the desired language):
/LANG/.mo
/languages/LANG/.mo
/locale/LANG/.mo
/locale/LC_MESSAGES/LANG/.mo
under unix-like systems it will also look in
/usr/share/locale/LANG/LC_MESSAGES/.mo
as well as using the short part of the language (e.g. if it is "es_ES" or "es_ES.UTF-8" and it doesn't exist it will also try "es")"
I could not find any more informations about how to use DefaultTranslator until i found your solution. Thanks!