Localizing an application

Depending on the kind of application, localization can become much more than having the strings that appear in the GUI available in different languages. If you came to learn about those more in-depth techniques, dealing with formatting and using ICU etc., this isn't the article you seek... This article discusses the relatively simple problem of localizing an app's GUI strings.

1. Changes to the source code

The needed changes to the source code are minimal. You just have to include the Catalog.h header and use the macros it provides on all the strings that appear in the GUI. The macros are:

  • B_TRANSLATION_CONTEXT gives a hint to the people that later translate your strings where those appear. So entering

    #define B_TRANSLATION_CONTEXT "MainWindow"

    will designate the following strings to belong to the "MainWindow".

  • B_TRANSLATE_SYSTEM_NAME is reserved for the app's name, e.g. here it's used in the window title of an "AwesomeApp":

    BWindow(frame, B_TRANSLATE_SYSTEM_NAME("AwesomeApp"), B_TITLED_WINDOW,
  • B_TRANSLATE is the usually deployed macro to mark a string to be translated. For example:

    BString *string = new BString(B_TRANSLATE("Invert selection"));
  • B_TRANSLATE_COMMENT allows you to leave an explanatory comment for the translators. For example:

    BString string = B_TRANSLATE_COMMENT("%s% settings", "Don't translate the variable %s%");

2. Changes to the Makefile

You find a sample Makefile at /system/develop/etc/Makefile that includes Haiku's makefile-engine which greatly simplifies things.

  • You have to fill in the APP_MIME_SIG, e.g. "APP_MIME_SIG = application/x-vnd.AwesomeApp".

  • As you have included Catalog.h in the source, don't forget to add localestub to the LIBS section.

  • Under LOCALES you list the two-letter language codes you'll provide, e.g. "LOCALE = en de es fr ja".

3. Creating "catkeys"

"catkeys" are the plain text files that contain your strings, the context you assigned, optionally an explanatory comment, and the (to be) translated string.

You start by creating the English version – en.catkeys – like this:

make catkeys

This will create a folder locales with the en.catkeys in it. You'll duplicate this file, rename it to e.g. de.catkeys and send it to your German friend for translation. Here are the first lines of a catkeys file:

1	English	application/x-vnd.AwesomeApp	680205015
Add to ignore list					ListView						Add to ignore list
Found no matches.					ListView						Found no matches.
Show application path					SetupWindow				Show application path

The first line always starts with a "1", then the language, the app's signature, and a checksum. The checksum has to stay the same across all translations!
Then follow the rows of strings; the 1st column for the original string, the 2nd column shows the context, then optionally a comment, and the translated string last.

The translator must only work on the last column string (and possibly replace the "English" of the first line with their language name in English, e.g. "German". But that is only for human readers of that file, it doesn't matter when compiling the application).

You and your translators can have a much more convenient and safe way to work with catkeys files by installing CatKeysEditor from the HaikuDepot. It provides a simple and clean interface to the otherwise confusing string jungle presented when opening catkeys in a text editor...

4. Compiling the application

After you've got back all those translated catkeys and put them in the locales folder, you compile your app like this:

make bindcatalogs

So, after the regular built, you do the make bindcatalogs to put the catalogs created from the catkeys into the executable's resources.

There's a thread "Catkeys translators needed for 3rd party apps" in the forum. If you need catkeys translations for your apps, you may want to post a request there.