Coding

Ubuntu Development > Internationalization Guide > Coding

STILL IN DRAFT STATUS

Introduction

In order to prepare your application to be translatable, you'll need to do the following:

  • PO folder - Creation of the directory containing the translation template and translations

  • Build system changes - Modifications to the build system to use gettext and intltool to extract translatable strings from the code, produce a translation template for translators and build message catalogs to load the translations from

  • Code changes - Modifications in the code to enable the use of translations

  • Marking strings for translation - Mark strings in the code for translation

  • Marking additional files for translation - Mark additional files (.desktop files, .schema files, etc.) for translation

Recommended directory layout for translations

It is recommended to use the standard GNU layout, in which translation templates and translations reside in the same directory at the top level in the source tree. Therefore, it is customary to create a single po folder for this purpose, so here's the first step:

  1. PO folder - Create a po folder at the top of your source tree

Most applications produce a single template, as it is easier to load the translations from a single domain and also helps the work of translators to have all strings in one single file. However, sometimes you'll need to create different templates, in which cases this is the recommended layout:

template1/template1.pot
template2/template2.pot
...

(i) Some developers prepend po- to the directory name to mark that they are used for translations, but this is up to you.

(i) If your application produces translatable xml documentation, it is customary to place the generated templates under /help/po

Build system changes

Autotools

If your application is using autotools, here are the changes required to the build system

Changes in configure.ac

You'll need to add the following to your top level directory's configure.ac file, substituting your-application-domain-name by the appropriate domain name. This is generally the name of your application in lowercase.

GETTEXT_PACKAGE=your-application-domain-name
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [gettext package name])
AM_GLIB_GNU_GETTEXT

# AM_GNOME_GETTEXT above substs $DATADIRNAME
# this is the directory where the *.{mo,gmo} files are installed
localedir='${prefix}/${DATADIRNAME}/locale'
AC_SUBST(localedir)

IT_PROG_INTLTOOL([0.40.0])

AC_OUTPUT([
po/Makefile.in
])

(i) This assumes you are using intltool, so remember to run intltoolize once before calling ./configure. This will create the po/Makefile.in.in file, necessary to generate the po/Makefile.in file specified in AC_OUTPUT. More info on AC_OUTPUT
(i) If your application uses any other internationalizable files (e.g. Freedesktop entries, Gconf schema files, PolicyKit policy files, see below) remember to add them in AC_OUTPUT as well. It may be as simple as:

AC_OUTPUT([
po/Makefile.in
data/myapp.desktop
data/myapp.schemas
data/myapp.policy
])

Changes in Makefile.am

General

Add the /po subdir to the toplevel Makefile.am file

SUBDIRS = po

If you are using Freedesktop.org desktop entries

You'll need to use intltool and add the following lines to the toplevel Makefile.am file, substituting yourappname by the appropriate name of your desktop entry and adding more if necessary to desktop_in_files.

desktopdir = $(datadir)/applications
desktop_in_files = yourappname.desktop.in
desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
@INTLTOOL_DESKTOP_RULE@

EXTRA_DIST = \
        $(desktop_in_files)      \

DISTCLEANFILES = \
        $(desktop_DATA) \

If you are using Gconf schema files

You'll need to use intltool and add the following lines to the toplevel Makefile.am file, substituting yourappname by the appropriate name of your schemas and adding more if necessary to schema_in_files.

schema_in_files = yourappname.schemas.in
schemadir = @GCONF_SCHEMA_FILE_DIR@
schema_DATA = $(schema_in_files:.schemas.in=.schemas)
@INTLTOOL_SCHEMAS_RULE@

EXTRA_DIST = \
        $(schema_in_files)      \

DISTCLEANFILES = \
        $(schema_DATA) \
  • Marking the files for internationalisation:

If you are using Policykit policy files

You'll need to use intltool and add the following lines to the toplevel Makefile.am file, substituting yourappname by the appropriate name of your policies and adding more if necessary to policy_in_files.

policydir = $(YOURAPPS_POLICY_DIR)
policy_in_files = yourappname.policy.in
policy_DATA = $(policy_in_files:.policy.in=.policy)

@INTLTOOL_POLICY_RULE@

EXTRA_DIST = \
        $(policy_in_files) \

DISTCLEANFILES = \
        $(policy_DATA)
  • Marking them for internationalisation: TODO: prepare a separate section on policy files, including the snippet below

  <action id="org.freedesktop.systemtoolsbackends.set">
    <_description>Manage system configuration</_description>
    <_message>System policy prevents modifying the configuration</_message>
    <defaults>
      <allow_inactive>no</allow_inactive>
      <allow_active>auth_admin</allow_active>
    </defaults>
  </action>

Other required files

  • po/LINGUAS
  • po/POTFILES.in
  • [optional] po/POTFILES.skip

Python-distutils-extra

Individual programming languages

C application

Code changes

Enabling gettext

Marking strings for translation

  • Mention gettext _()
  • Mention ngettext

Python application

Other aspects

Translator comments

Translator credits

GTK

KDE

Launchpad

Launchpad

Launchpad integration library

Ubuntu applications use the Launchpad integration library to provide shortcuts to Launchpad to obtain help, report bugs and submit translations. You can see it in action in any Ubuntu application's Help menu:

../LPI.png

(i) Note that this only works for Ubuntu packages available in the repositories. The Launchpad integration library does not work with PPAs or other projects hosted in Launchpad.

It has bindings for several languages. Some examples

Python with GtkBuilder

   1 import LaunchpadIntegration
   2 LaunchpadIntegration.set_sourcepackagename('my_app')
   3 LaunchpadIntegration.add_items(self.builder.get_object('menu_help'), 0, False, True)

Assuming self.builder is a gtk.Builder object where the UI is loaded, the first argument in the add_items method is the widget where to add the menu items (a menu we've called 'menu_help'), the second one is their position in the menu shell, and the last two ones specify whether to show spearators on the top and bottom, respectively.

Here is also another example on how Launchpad integration was added to Pitivi.

C# with Glade

   1 using LaunchpadIntegration;
   2 public class GladeApp
   3 {
   4         [Glade.Widget] Gtk.Menu help_menu;
   5 
   6         public static void Main (string[] args)
   7         {
   8                 Glade.XML gxml = new Glade.XML (null, "gui.glade", "window1", null);
   9                 LaunchpadIntegration.LaunchpadIntegration.SetSourcePackageName ("my_app")
  10                 LaunchpadIntegration.AddItems (self.builder.get_object("help_menu"), 0, false, true)
  11         }
  12 }

C

Here's an example in C of how support for this library was added to Empathy:

   1 === modified file 'configure.ac'
   2 --- configure.ac        2009-10-13 03:20:58 +0000
   3 +++ configure.ac        2009-10-13 03:26:58 +0000
   4 @@ -131,6 +131,7 @@
   5     gstreamer-0.10
   6     unique-1.0
   7     gnome-keyring-1 >= $KEYRING_REQUIRED
   8 +   launchpad-integration
   9  ])
  10  
  11  PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= $LIBNOTIFY_REQUIRED)
  12 
  13 === modified file 'src/empathy-main-window.c'
  14 --- src/empathy-main-window.c   2009-10-13 03:20:58 +0000
  15 +++ src/empathy-main-window.c   2009-10-13 18:15:41 +0000
  16 @@ -27,6 +27,9 @@
  17  #include <gtk/gtk.h>
  18  #include <glib/gi18n.h>
  19  
  20 +/* Add launchpad hooks */
  21 +#include <launchpad-integration.h>
  22 +
  23  #include <libempathy/empathy-contact.h>
  24  #include <libempathy/empathy-utils.h>
  25  #include <libempathy/empathy-account-manager.h>
  26 @@ -1424,6 +1427,9 @@
  27  
  28         main_window_update_status (window, window->account_manager);
  29  
  30 +       /* Add launchpad hooks */
  31 +       launchpad_integration_add_ui (window->ui_manager, "/menubar/help/LaunchpadItems");
  32 +
  33         return window->window;
  34  }
  35  
  36 
  37 === modified file 'src/empathy-main-window.ui'
  38 --- src/empathy-main-window.ui  2009-10-13 03:19:42 +0000
  39 +++ src/empathy-main-window.ui  2009-10-13 18:17:20 +0000
  40 @@ -243,6 +243,7 @@
  41          <menu action="help">
  42            <menuitem action="help_contents"/>
  43            <menuitem action="help_debug"/>
  44 +          <placeholder name="LaunchpadItems"/>
  45            <menuitem action="help_about"/>
  46          </menu>
  47        </menubar>

Additional documentation


CategoryUbuntuDevelopment CategoryTranslations

UbuntuDevelopment/Internationalisation/Coding (last edited 2010-02-18 10:50:22 by 28)