Forum > Translations

Package translation

(1/1)

CCRDude:
Hi,

I'm trying to move some code into packages to simplify things.
So far I had resourcestrings where they "belonged".
Seeing how lclstrconsts is embedded, I moved them into a single unit for the whole package.

This wiki page speaks about unit LResources and a manually created TPoTranslator, but this is all kind of Lazarus 0.9 code it seems.

What do I need to add to the package to make it use translated strings?

Within my main code, I do:


--- Code: ---      r := Translations.TranslateUnitResourceStrings('LCLStrConsts', sPODirectory + 'lclstrconsts.%s.po', sLanguage, sFallbackLanguage);
      r := Translations.TranslateUnitResourceStrings('MyResourceStringUnit', sPODirectory + 'MyResourceStringUnit.%s.po', sLanguage, sFallbackLanguage);

--- End code ---

Return result is "ok".

I got the LCLStrConsts from somewhere on the FreePascal site, but now that I think of it, my dialogs have english labels anyway, so it might be that's wrong?

The code above is called before Application.Initialize (the example has it in a FormCreate), where I first evaluate stored language preferences and command line parameters.

This page mentions to simply add LCLStrConsts to the program, but that doesn't change dialog button captions as well. SetDefaultLang does not help.

Is there any up to date tutorial, or hints what I'm doing wrong?

wp:

--- Quote from: CCRDude on December 18, 2023, 10:47:23 am ---I'm trying to move some code into packages to simplify things.
So far I had resourcestrings where they "belonged".
Seeing how lclstrconsts is embedded, I moved them into a single unit for the whole package.

--- End quote ---
Yes, the advantage is that you need less calls to TranslateUnitResourceStrings in your application


--- Quote from: CCRDude on December 18, 2023, 10:47:23 am ---What do I need to add to the package to make it use translated strings?

--- End quote ---
In the package options you find the "i18n" item again. Check "Enable i18n" and enter a path to the translation files within your package folder, check "Create/update .po file when saving a lfm file". Then define strings as resource strings and, ideally, collect them in a "strings" unit of the package (similar to lclstrconsts). Within your package units do not assign strings directly, always assign the resoure strings. Once the package has reached some stable state begin to translate the po files created by the IDE. For this, copy the .pot file (t = template) and give the copy the extension .<lang>.po where <lang> is the abbreviated language code, e.g. de for German; open this .po file in a translation utility such as POEdit and translate the individual strings - it's pretty much self-explanatory. In case of English (or the language in which your resource strings are contained in the "strings" unit), you just copy the original strings into the tranlation column (in case of POEdit you can simply press CTRL+B).

When it comes to application of your translation-aware package you must activate "i18n" in the project options now and specify a path for the translation files within your project, relative to the project binary so that it can be found when the application runs. "i18n" makes the IDE generate po files for the resource strings in your application. In order to access also the strings of the used packages, you must copy the po files of these packages into the languages folder of your project. Then your project must provide code to execute the translation whenever needed: add unit "Translations" to "uses" and call TranslateUnitResourceStrings with the unitname and the path to the po file as parameters. You may add LCLTranslator to the uses clause, it takes care of preparing the strings from the lfm file to the po file system (it may lead to duplicate items, though, which are harmful but annoying since they create additional work for your translators).

See attached demo which can be switched between English and German. Besides the LCL strings, it also uses some strings from the TAChart package. It also uses a component, TAChartCombobox, of that package and displays its strings in the selected language.

Important side-detail: Do not delete the .lrj file, it is needed to generate the po file. If you work with a version control system such as SVN or GIT, put it under version control.

CCRDude:
Thank you so much for your detailed answer!

Your example looks very much like my code, so at least I knew I was going into the right direction.

I was using e.g. "de-de" as the language, while .po files had "de_DE". This worked for the main application localization (maybe because of an now unnecessary call to TranslateResourceStrings), but not for packages.

I renamed my localization files to use underscores, and now they work fine. Thank you so much for giving me that example :)

To make things more comfortable, I'll look into a better way to trigger the .pot creation in the future :)

Navigation

[0] Message Index

Go to full version