Coding
Getting Started |
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:
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 ...
Some developers prepend po- to the directory name to mark that they are used for translations, but this is up to you.
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 ])
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
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:
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
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
GNOME l10n guidelines for developers and the GNOME Translation Project
Bill Poser's "Controlling your locale with environment variables" article
UbuntuDevelopment/Internationalisation/Coding (last edited 2010-02-18 10:50:22 by 28)