GNU gettext for Delphi, C++ Builder and Kylix 1.2 beta
<<< Previous | Action | Next >>>

# Database applications

## Preventing unwanted translations

When you create a database application, there will be a lot of component properties that you don't want to be translated when using `Translatecomponent()`. Typically, the field names, table names and even database names of a database have meaningful translations, and the translation file from the translator may include translations for field names. Also, SQL statements should not be translated. They will get extracted, but if the translator modifies them, it would most likely break your program if this translation would be applied.

Therefore, it is very important, that you consult the appendix called How to handle specific classes> to see what ignores you should add to your application. Make sure that these ignores are executed before the first call to `TranslateComponent()`. The list in that appendix may not be complete - especially not if you use database components that are not mentioned. Therefore you must have a look at your components and make sure, that all properties, that should not be translated, have a corresponding `TP_GlobalIgnoreClassProperty()` call.

## DisplayLabel property explained

Delphi is very good for creating a single-language database application, fast, if the application only needs one language. A typical single-language application uses field names that are easily understood, like "Name", "Address" etc. Let's assume that you use a query component with an SQL statement like this:

    select * from customer order by Name

In this case, the name of the `Name` field of the `customer` table will propagate through all components, will become the column heading of a TDBGrid etc. Your grid column for names will read "Name". This is desired in an English language application, but absolutely not in all other languages.

The solution is to modify the `.DisplayLabel` property of the `TField` components, that your dataset possesses. Every `TDataset` descendant has a `.Fields[]` property that refers to the fields in the dataset, and all these field components are descendants of `TField`, which has the `TField.DisplayLabel` property.

Delphi provides two ways to modify this `DisplayLabel` property: At runtime and at design time, which leads to two different ways of handling the localization of it.

## Setting displaylabel at runtime

The runtime assignment solution is to assign a displaylabel at runtime like this:

    procedure TForm1.Query1AfterOpen(DataSet: TDataSet);
    begin
      Dataset.FieldByName('Name').DisplayLabel:=_('Name');
    end;

This way, the field names are always the same in the database and the entire application, but the user will see a localized name. This works for all dataset type components, including table components, TClientDataset etc.

## Display label at design time

Creating design-time DisplayLabel properties goes like this:

- Double-click the dataset component. This brings up the field list window.

- Click with your right mouse button on the field list window and choose "Add all fields". This requires your dataset to be able to actually fetch data from the database at design time, but will add all the fields of the dataset to the field list window.

- Make sure that the form (or datamodule) that the dataset component is on, is translated using `TranslateComponent()` before the dataset is opened. This means that the dataset needs to be closed by default, and that you have to open the dataset at runtime using `.Open` or `.Active:=True`.

By doing this, the field names will be present in the DFM files, and will therefore be extracted for the translator to be translated. Now, `TranslateComponent()` will translate the `TField.DisplayLabel` values:

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      TranslateComponent (self);
      Query.Open;
    end;

## Multiple field name translations

Sometimes it is very handy to have field names translated to something else than what you put into the `.DisplayLabel` property. For instance, you may want to have a short version for exported ASCII files, another version for exporting XML files, one version for reports, and again another version for the `.DisplayLabel` property.

This is easily done by using several po files (which is the same as multiple text domains). The part of your program that writes a column header to an ascii file might look like this:

    write (mytextfile,dgettext('fieldnames',myfield.FieldName));

This will find the field name in the `fieldnames.mo` file and output the translation. The `fieldnames.po` template can be written by hand (using notepad), or sometimes be extracted from a datamodule. Often, the number of field names is so low that the quickest solution is to write the po file by hand.

<<< Previous | Home | Next >>>
Plural forms | Up | Translation repositories