Difference between revisions of "Internationalisation programmation"
(12 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
== Why == | == Why == | ||
− | The common method using resource strings | + | The common I18N method using resource strings requires a development environment and programming skills to make or improve translations. |
− | |||
− | + | For Gestinux, we have used another system. | |
− | Translation are read by the software from mere | + | Translation are read by the software from mere text files (inifile like) and read when forms are loaded. This is quick enough. |
− | This way, it is possible to define or modify translations directly when running the application, without developing tools and skills. | + | This way, it is possible to define or modify translations directly when running the application, without developing tools and skills. There is no need to recompile anything to add a new language, or to modify an existing language. |
+ | |||
+ | GTranslator is an utility integrated in the application, to make and check translations easily. | ||
+ | |||
+ | It is also possible to toggle between 2 languages at runtime, to check a new translation. | ||
== How it works ? == | == How it works ? == | ||
Line 14: | Line 17: | ||
=== Language file === | === Language file === | ||
− | + | Translation are stored in text files, referred as '''language files'''. | |
− | + | There are two language files for each language, and they are merged at startup in a single Inifile in memory. | |
+ | |||
+ | To locate, or create or improve a translation, see [[Translating#The_code_for_your_language|this page]]. | ||
=== Simple controls === | === Simple controls === | ||
− | For each control of [[Gestinux_util]], the translation is | + | For each control of [[Gestinux_util]], the translation is searched in the language file : |
− | The section is the Form name. | + | The section is the Form name (the form class name in version under development). |
The parameter name is the component name, followed by a dot and the property name to translate. | The parameter name is the component name, followed by a dot and the property name to translate. | ||
The parameter value is the translation | The parameter value is the translation | ||
Line 31: | Line 36: | ||
E.g : | E.g : | ||
− | [FormConnection] | + | [FormConnection] |
− | + | LabelUsername.Caption=Username | |
− | LabelUsername.Caption=Username | + | EditUsername.Hint=Enter your username |
− | + | BtnOk.caption=Connect | |
− | EditUsername.Hint=Enter your username | + | BtnOk.Hint=Click here to connect |
− | + | MenuItemQuit.Caption=Exit | |
− | BtnOk.caption=Connect | ||
− | |||
− | BtnOk.Hint=Click here to connect | ||
− | |||
− | MenuItemQuit.Caption=Exit | ||
=== GGrid and GDbGrid === | === GGrid and GDbGrid === | ||
For each column, indexed by its position, we can define the title. | For each column, indexed by its position, we can define the title. | ||
− | The ''Columns'' property must be defined to allow translations (and other features). | + | The ''Columns'' property must be defined, and all columns must be added, to allow translations (and other features). |
E.g : | E.g : | ||
− | + | GridEmployees.Name.Title=Name | |
+ | GridEmployees.Address.Title=Address | ||
+ | GridEmployees.City.Title=City | ||
− | + | === Messages === | |
+ | |||
+ | MessageDlg and ShowMessage procedures must not be used, since they don't use the same translation system. | ||
− | |||
− | |||
− | |||
Messages are identified by keywords not used for control's translations. They are stored in the form section, along with other control's translations. | Messages are identified by keywords not used for control's translations. They are stored in the form section, along with other control's translations. | ||
− | Parameters are allowed. | + | Parameters are allowed. |
− | + | Example : | |
− | + | UsernameConnectError=%0:s in not a valid username, retry. | |
To display a translated message, use only one of these functions member of TGForm : | To display a translated message, use only one of these functions member of TGForm : | ||
− | + | AbortMessage ( 'UsernameConnectError', [EditUsername.Text] ); | |
− | + | ErrorMessage ( 'UsernameConnectError', [EditUsername.Text] ); | |
− | + | ConfirmationMessage ( 'UsernameConnectError', [EditUsername.Text] ); | |
+ | InformationMessage ( 'UsernameConnectError', [EditUsername.Text] ); | ||
− | + | The message form displays an Help button, which opens by default the wiki page named after the HelpUrl property of the form. | |
+ | There is also a button to copy the message in the clipboard, to paste it somewhere else. | ||
− | + | In some special cases, a more general procedure can be used : | |
+ | |||
+ | DisplayMessage ( ParentForm, Section, MessageId, [parameter-1, ..., parameter_n], Severity, WikiPage ); | ||
=== Other strings === | === Other strings === | ||
− | Other parameters can be present in the | + | Other parameters can be present in the language file, for special usages. |
Their translations can be queried at any time by : | Their translations can be queried at any time by : | ||
− | TranslateText( Section, Key, Default ); | + | TranslateText( Section, Key, Default ); |
+ | |||
+ | or | ||
+ | |||
+ | TranslateMessage ( Section, Key, [parameter_1, ... parameter_n] ); | ||
+ | |||
+ | When these procedures are used, and to enable dynamic translation (triggered by F4 key), a Translate method must generally be added in the form, overriding the ancestor, and calling the TranslateText or TranslateMessage for the new language. | ||
+ | |||
+ | Example : | ||
+ | |||
+ | procedure TFormAccountingEntries.DisplayNotSelected; | ||
+ | begin | ||
+ | if NumberSelected = 0 then | ||
+ | LabelNotAllSelected.Caption := '' | ||
+ | else | ||
+ | LabelNotAllSelected.Caption := | ||
+ | Format(TranslateText(Name, 'NotAllRecordsSelected'), [MaxRecordsSelected]); | ||
+ | end; | ||
+ | |||
+ | procedure TFormAccountingEntries.Translate; | ||
+ | begin | ||
+ | inherited Translate; | ||
+ | DisplayNotSelected; | ||
+ | end; | ||
== How to make a translation == | == How to make a translation == | ||
Use the [[Translating|translation utility]], available for Linux and for Windows, which can read a reference language file, and fill another language file, detecting missing translations. | Use the [[Translating|translation utility]], available for Linux and for Windows, which can read a reference language file, and fill another language file, detecting missing translations. |
Latest revision as of 13:04, 18 November 2015
Why
The common I18N method using resource strings requires a development environment and programming skills to make or improve translations.
For Gestinux, we have used another system.
Translation are read by the software from mere text files (inifile like) and read when forms are loaded. This is quick enough.
This way, it is possible to define or modify translations directly when running the application, without developing tools and skills. There is no need to recompile anything to add a new language, or to modify an existing language.
GTranslator is an utility integrated in the application, to make and check translations easily.
It is also possible to toggle between 2 languages at runtime, to check a new translation.
How it works ?
Language file
Translation are stored in text files, referred as language files.
There are two language files for each language, and they are merged at startup in a single Inifile in memory.
To locate, or create or improve a translation, see this page.
Simple controls
For each control of Gestinux_util, the translation is searched in the language file :
The section is the Form name (the form class name in version under development). The parameter name is the component name, followed by a dot and the property name to translate. The parameter value is the translation
If the file or the parameter is not found, the design properties are used.
E.g :
[FormConnection] LabelUsername.Caption=Username EditUsername.Hint=Enter your username BtnOk.caption=Connect BtnOk.Hint=Click here to connect MenuItemQuit.Caption=Exit
GGrid and GDbGrid
For each column, indexed by its position, we can define the title. The Columns property must be defined, and all columns must be added, to allow translations (and other features).
E.g :
GridEmployees.Name.Title=Name GridEmployees.Address.Title=Address GridEmployees.City.Title=City
Messages
MessageDlg and ShowMessage procedures must not be used, since they don't use the same translation system.
Messages are identified by keywords not used for control's translations. They are stored in the form section, along with other control's translations.
Parameters are allowed.
Example :
UsernameConnectError=%0:s in not a valid username, retry.
To display a translated message, use only one of these functions member of TGForm :
AbortMessage ( 'UsernameConnectError', [EditUsername.Text] ); ErrorMessage ( 'UsernameConnectError', [EditUsername.Text] ); ConfirmationMessage ( 'UsernameConnectError', [EditUsername.Text] ); InformationMessage ( 'UsernameConnectError', [EditUsername.Text] );
The message form displays an Help button, which opens by default the wiki page named after the HelpUrl property of the form. There is also a button to copy the message in the clipboard, to paste it somewhere else.
In some special cases, a more general procedure can be used :
DisplayMessage ( ParentForm, Section, MessageId, [parameter-1, ..., parameter_n], Severity, WikiPage );
Other strings
Other parameters can be present in the language file, for special usages. Their translations can be queried at any time by :
TranslateText( Section, Key, Default );
or
TranslateMessage ( Section, Key, [parameter_1, ... parameter_n] );
When these procedures are used, and to enable dynamic translation (triggered by F4 key), a Translate method must generally be added in the form, overriding the ancestor, and calling the TranslateText or TranslateMessage for the new language.
Example :
procedure TFormAccountingEntries.DisplayNotSelected; begin if NumberSelected = 0 then LabelNotAllSelected.Caption := else LabelNotAllSelected.Caption := Format(TranslateText(Name, 'NotAllRecordsSelected'), [MaxRecordsSelected]); end; procedure TFormAccountingEntries.Translate; begin inherited Translate; DisplayNotSelected; end;
How to make a translation
Use the translation utility, available for Linux and for Windows, which can read a reference language file, and fill another language file, detecting missing translations.