Difference between revisions of "Translations / i18n / localizations for programs"

From Free Pascal wiki
Jump to navigationJump to search
Line 27: Line 27:
  
 
For every language the .po file must be copied and translated. The LCL translation unit uses the common language codes (en=english, de=german, it=italian, ...) to search. For example the german translation of unit1.po would be unit1.de.po. This means, copy the unit1.po file to unit1.de.po, unit1.it.po, and whatever language you want to support and then the translators can edit their specific .po file.
 
For every language the .po file must be copied and translated. The LCL translation unit uses the common language codes (en=english, de=german, it=italian, ...) to search. For example the german translation of unit1.po would be unit1.de.po. This means, copy the unit1.po file to unit1.de.po, unit1.it.po, and whatever language you want to support and then the translators can edit their specific .po file.
 +
 +
'''Note to brazillians/portugueses:''': Lazarus IDE and LCL have only brazillian portuguese translations and these files are 'pb.po' extensions and not 'pt.po'.
  
 
==IDE options for automatic updates of .po files==
 
==IDE options for automatic updates of .po files==
  
 
*The unit containing the resource strings must be added to the package or project.
 
*The unit containing the resource strings must be added to the package or project.
*You must provide a .po path, this means a separate directory. For example: create a sub directory ''language'' in the package / project directory. For projects see the Project > Project Options. For packages see Options > IDE integration.
+
*You must provide a .po path, this means a separate directory. For example: create a sub directory ''language'' in the package / project directory. For projects go to the Project > Project Options. For packages go to Options > IDE integration.
  
 
==Translating at start of program==
 
==Translating at start of program==
Line 37: Line 39:
 
For every .po file, you must call TranslateUnitResourceStrings of the LCL translations unit. For example:
 
For every .po file, you must call TranslateUnitResourceStrings of the LCL translations unit. For example:
  
 +
<pascal>
 +
    {First of all: add "gettext" and "translations" units in uses clause}
 
     procedure TForm1.FormCreate(Sender: TObject);
 
     procedure TForm1.FormCreate(Sender: TObject);
 
     var
 
     var
 
       PODirectory, Lang, FallbackLang: String;
 
       PODirectory, Lang, FallbackLang: String;
 
     begin
 
     begin
       PODirectory:='/path/to/lazarus/lcl/languages/';
+
       PODirectory := '/path/to/lazarus/lcl/languages/';
       GetLanguageIDs(Lang,FallbackLang); // in unit gettext
+
       GetLanguageIDs(Lang, FallbackLang); // in unit gettext
       TranslateUnitResourceStrings('LCLStrConsts',PODirectory+'lcl.%s.po',
+
       TranslateUnitResourceStrings('LCLStrConsts', PODirectory + 'lclstrconsts.%s.po', Lang, FallbackLang);
                                  Lang,FallbackLang);
+
       MessageDlg('Title', 'Text', mtInformation, [mbOk, mbCancel, mbYes], 0);
       MessageDlg('Title','Text',mtInformation,[mbOk,mbCancel,mbYes],0);
 
 
     end;
 
     end;
 +
</pascal>

Revision as of 18:43, 18 February 2008

Overview

This is about how a program can use different strings for various languages like english, chinese, german, finnish, italian, ... . Basically it works like this: Add a resourcestring for every caption, compile to get the .rst and/or .po files (the IDE can do this automatically), create one translated .po file for each language (there are free graphical tools) and use the functions of the LCL translations unit to load the right one at start of the program.

Resourcestrings

For example

 resourcestring
   Caption1 = 'Some text';
   HelloWorld1 = 'Hello World';

These are like normal string constants, that means you can assign them to any string. For example

 Label1.Caption := HelloWorld1;

When fpc compiles them, it creates for each unit a file unitname.rst, containing the resourcestring data (name + content).

.po Files

There are many free graphical tools to edit .po files, which are simple text like the .rst files, but with some more options, like a header providing fields for author, encoding, language and date. Every fpc installation provides the tool rstconv (windows: rstconv.exe). This tool can be used to convert a .rst file into a .po file. The IDE can do this automatically. Examples for free tools: kbabel, poedit.

Example using rstconv directly:

 rstconv -i unit1.rst -o unit1.po

Translating

For every language the .po file must be copied and translated. The LCL translation unit uses the common language codes (en=english, de=german, it=italian, ...) to search. For example the german translation of unit1.po would be unit1.de.po. This means, copy the unit1.po file to unit1.de.po, unit1.it.po, and whatever language you want to support and then the translators can edit their specific .po file.

Note to brazillians/portugueses:: Lazarus IDE and LCL have only brazillian portuguese translations and these files are 'pb.po' extensions and not 'pt.po'.

IDE options for automatic updates of .po files

  • The unit containing the resource strings must be added to the package or project.
  • You must provide a .po path, this means a separate directory. For example: create a sub directory language in the package / project directory. For projects go to the Project > Project Options. For packages go to Options > IDE integration.

Translating at start of program

For every .po file, you must call TranslateUnitResourceStrings of the LCL translations unit. For example:

<pascal>

   {First of all: add "gettext" and "translations" units in uses clause}
   procedure TForm1.FormCreate(Sender: TObject);
   var
     PODirectory, Lang, FallbackLang: String;
   begin
     PODirectory := '/path/to/lazarus/lcl/languages/';
     GetLanguageIDs(Lang, FallbackLang); // in unit gettext
     TranslateUnitResourceStrings('LCLStrConsts', PODirectory + 'lclstrconsts.%s.po', Lang, FallbackLang);
     MessageDlg('Title', 'Text', mtInformation, [mbOk, mbCancel, mbYes], 0);
   end;

</pascal>