Search code examples
lazarusfreepascal

Lazarus localization / multiple projects


I've got some Delphi experience and I'm trying to build a project with Lazarus, which is completely new for me.

I think, I've read all information available about Lazarus,Translating/Internationalization/Localization, but I was unable to find what I really want.

I've been working in a project with 3 or 4 EXEcutables, that share between them, the same database the same Interface (form inheritance), common utils, settings, and common and related strings.

I don't want to have 3 or 4 .po files with different names (one for each EXE) , with the same common strings shared between them.

Is there a solution for that?

  • probably force ONE "gobal.po" for all Apps? how?
  • do I have to create my own system to localize \ centralize all strings in ONE file?

any suggestions?

thanks for any help. regards,


Solution

  • Use a shared language unit into which you put all the strings of all projects. Create a package into which you add this shared strings unit. Turn i18n on for this package. Compile the package and you'll get the shared po file in the languages folder.

    For every project needing the resource strings, you must add this package as a requirement - the easiest way to do this is in the package editor and to select "Use" / "Add to project".

    Don't turn on i18n for the projects because this would add the project po files to the languages folder.

    In order to use translated strings in each project, add the unit "Translations" to uses and call

    TranslateUnitResourceStrings(
      StringsUnit, 
      Format('languages\%s.%s.po', [StringsUnit, ALang])
    );
    

    Here StringsUnit is the name of the shared unit with all the collected resource strings. ALang is the language symbol to be used, e.g. 'de' for German, 'fr' for French etc.

    And now the hard part... Since i18n is off, the strings assigned to captions of components are not automatically put into the po file. So, you leave the component captions alone, create a resource string for each one (in the 'stringsunit', of course), and then, at runtime, assign the captions to the resourcestring. Maybe something like this:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      SetCaptions;
    end;
    
    procedure TForm1.SetCaptions;
    begin
      Caption := RSTitleOfForm1;         // resource string for form title
      Label1.Caption := RSYDateLabel;    // label caption showing "Date:"
      // etc.
    end;
    

    If the user selects a new language, for example from a combobox with all the available translations, you must call TranslateUnitResourceStrings and then SetCaptions for each existing form (in case of dynamically created forms, SetCaptions will be called automatically since it is in the FormCreate event).