Recent

Author Topic: Translate from resources  (Read 5965 times)

Sieben

  • Sr. Member
  • ****
  • Posts: 310
Translate from resources
« on: November 17, 2021, 07:34:53 pm »
I would like to make a suggestion here for what I think is a quite simple and convenient way of handling i18n po files. For this, the po files have to be added to your project via Project -> Options -> Resources (setting 'FPC resources' in Project -> Options -> Miscellaneous). They should be loaded from their original location, where they are also created and maintained.

Above all and in almost any case this is lclstrconsts.xy.po (from Lazarus lcl/languages) if you want localized messages, dialog buttons etc; then projekt.xy.po (from the project's po folder) if you want to provide localized versions of your app, and, if package or custom unit translation is also required, the corresponding *.xy.po (from the respective package po folders), where 'xy' stands for the respective language id.

Simply leave the naming of the resources to the IDE, so that project.xy.po becomes 'PROJECT.XY', lclstrconsts.xy.po -> 'LCLSTRCONSTS.XY' etc. Types should evaluate to RC_DATA. Package or custom unit translations require a simple text list with a single line per unit name, which should be named restrans.txt (default), and which is also loaded to resources (-> 'RESTRANS'). Of course, the corresponding additional po files must also be provided. The list is only required once, even if you provide po files for several languages.

Load the ResTrans package included below, compile it and add it to your project. Procedure TranslateFromResources() of unit rkResTrans then basically will do the same as SetDefaultLang() of the Lazarus LCLTranslator unit, only from resources. LResources.LRSTranslator will also be set and thus be available throughout the application. The routines won't throw an error if a particular resource is not included, but of course the resp. target unit won't be translated either.

For an automatic translation at the start of the program, simply include rkDefTrans unit in your project's uses, corresponding to the Lazarus DefaultTranslator unit. A resource called 'RESTRANS' for the list of additional units is automatically searched for, but a different name can be passed as a parameter. Your project po file(s) should be named according to your executable, just like with SetDefaultLang().

Now you only have to maintain the respective po files and, if necessary, restrans.txt 'on site', the IDE automatically pulls the latest versions from the originally specified location with each build. No more forwarding of the po files, no manual collection prior to release, no temporary unpacking of resources during runtime, no external tools like lazres.

To sum it up once more: if you just need to translate Lazarus (and FCL resources - cf here ff) - simply load the corresponding po files into the FPC resources of your project and include rkDefTrans in the uses. LCLStrConsts, RTLConsts, SysConst and DBConst po resources are searched for automatically. If you also need to translate your application resources, add your project.xy.po file(s); inclusion of RESTRANS is not necessary in both cases. If you also need to translate other units include RESTRANS list and provide the additional po files.

And of course any combination of this and 'standard' translation is also possible. So you can have LCLStrConsts etc translated from resources and still provide your users with the po file of your application in order to help you with translations or adjust it to their own needs.

If in doubt consult the source code. Or ask. Created and tested with Lazarus 2.0.10.
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: Translate from resources
« Reply #1 on: February 09, 2022, 05:30:59 pm »
Thank you for this contribution.

I modified it to suit my needs.
I used to have a unit that translated lclstrconst from old style (*.lrs) resources.
I wanted to update that to new style fpc resources for a long time now, but it was apparently not so high on my whishlist that I put the energy in to do it myself.

Looking at your code, it's even easier than using the old style resources.

I included the resources via the {$ filename.res} directive in the unit's implementation section and created the necessary resource using lazres (in ($lazarus)/tools).

So now any program that uses this unit has all lcl resourcestrings translated.

If anyone is interested you can find it here.
Just adapt it to use the language of your choice.
The instructions for creating the resource file are in the comments.
(The res file for dutch language resides in my repo as well, for convenience.)

Thanks again.

Bart

Sieben

  • Sr. Member
  • ****
  • Posts: 310
Re: Translate from resources
« Reply #2 on: February 10, 2022, 01:11:01 pm »
Nice to have some feedback, thank you very much! But even when you just want to translate lclstrconsts you could use my code right 'out of the box' as well - just add the .po-file to your project's resources (Project Options / Resources) and include rkDefTrans in the uses clause of your project. There's very little overhead in checking the other files supported, just a few calls to FindResource(). But you sure know that.

Anyway - I'm glad it works for you and that I could contribute sth useful here.
Lazarus 2.2.0, FPC 3.2.2, .deb install on Ubuntu Xenial 32 / Gtk2 / Unity7

Bart

  • Hero Member
  • *****
  • Posts: 5275
    • Bart en Mariska's Webstek
Re: Translate from resources
« Reply #3 on: February 10, 2022, 06:44:25 pm »
... But even when you just want to translate lclstrconsts you could use my code right 'out of the box' as well - just add the .po-file to your project's resources (Project Options / Resources) and include rkDefTrans in the uses clause of your project.

I know, I used rkDefTrans to make my own unit.
This way it's simpler for me: i just add it to the uses clause.
Every once in a while I just update the res file.

Bart

 

TinyPortal © 2005-2018