What is the best way to write an application for different languages?
What is gettext used for?
May 14th, 2000 20:22
Nathan Wallace
chuck
I'd suggest gettext - there is gettext support in php 3.0.something (6?
9?) and later, and in php4 (compile --with-gettext). There's not much
documentation right now, but it's pretty easy to use - you make the
translations, set the locale, and then put _() around all your strings,
and boom, it works. Fast, and also fairly standard.
Quick Primer on Using gettext
PHP's gettext functions provide an interface to working with the GNU gettext utility. gettext is a GNU utility that helps programmers internationalize programs. A brief and somewhat inaccurate description of internationalization (often abbreviated I18N) is that it is the process of making software portable to languages and cultures other than the originating language(s) and culture(s). gettext helps this process by providing a set of tools to help manage the messages output by the software.
Following is a brief overview of how to use gettext with a PHP script:
1. Get and install a copy of gettext. (See http://www.gnu.org/ for more details.)
2. Make sure PHP is built with gettext support (i.e., with --with-gettext on the ./configure command line).
3. Develop your script/application, writing the messages in the language of your choice. Our sample application looks like this:
<pre>
<?
// Write a small application to print "Good Morning!" in a variety of languages
// Rather than hard-code the greetings, use gettext to manage the translations
// Make an array
// Use the ISO two-letter codes as keys
// Use the language names as values
$iso_codes = array (
'en'=>'English',
'fr'=>'French',
'it'=>'Italian',
'pt'=>'Portuguese',
'es'=>'Spanish'
);
foreach ($iso_codes as $iso_code => $language) {
// Set the LANGUAGE enviroment variable to the desired language
putenv ('LANGUAGE='.$iso_code);
// Print out the language name and greeting
// Note that the greeting is wrapped in a call to gettext
printf ("<b>%12s:</b> %s/n", $language, gettext("Good morning!"));
}
?>
</pre>
3. Extract the translatable strings with the xgettext utility. (xgettext is part of the gettext utilities and is not a PHP function.) A sample command line for the utility might look like this:
xgettext /
--extract-all /
--c++ /
--default-domain=greetings /
--indent /
--omit-header /
--sort-output /
--width=76 /
gettext.php
Note
You may need different command line options than those noted above. For more information on xgettext, consult the gettext documentation or run xgettext --help.
xgettext parses the specified file (in the previous example, gettext.php), looking for strings of characters. From the found strings, xgettext generates a file called greetings.po, which looks something like this:
#: gettext.php:28
#, c-format
msgid "<b>%12s:</b> %s/n"
msgstr ""
#: gettext.php:28
msgid "Good morning!"
msgstr ""
Note that xgettext was designed for parsing C and C++ files, and ignores single-quoted strings.
Lines starting with # are comments.
msgid contains the text of the original, untranslated message.
msgstr contains the translated message.
4. Open the .po file in your favorite text editor and remove any messages that you don't want translated. This would probably leave us with something like this:
#: gettext.php:26
msgid "Good morning!"
msgstr ""
5. Create a directory to store the tranlations.
6. In the directory created in step 5, create one subdirectory for every language to which you will be translating. Name the directories for the ISO 639 language code - ar for Arabic, co for Corsican, en for English, and so on. See http://lcweb.loc.gov/standards/iso639-2/englangn.html for the codes.
7. In each subdirectory, create a subdirectory named LC_MESSAGES.
8. Place one copy of your .po file in every LC_MESSAGES directory.
9. Have your translators translate the messages in the .po file in the appropriate directory.
10. When the translations are ready, use the msgfmt utility to convert the .po files into the compact, binary format used by gettext. (msgfmt is another part of the gettext package, and is not a PHP function.) Basic syntax for converting the files is as follows:
msgfmt -o output_file.mo input_file.po
Note
You may need different command line options than those noted above. For more information on msgfmt, consult the gettext documentation or run msgfmt --help.
11. Modify your original script so that the gettext function knows where to find the translated versions:
<pre>
<?
// Bind a domain to directory
// Gettext uses domains to know what directories to
// search for translations to messages passed to gettext
bindtextdomain ('greetings', './translations');
// Set the current domain that gettext will use
textdomain ('greetings');
# Make an array
# Use the ISO two-letter codes as keys
# Use the language names as values
$iso_codes = array (
'en'=>'English',
'fr'=>'French',
'it'=>'Italian',
'pt'=>'Portuguese',
'es'=>'Spanish'
);
foreach ($iso_codes as $iso_code => $language) {
# Set the LANGUAGE environment variable to the desired language
putenv ('LANGUAGE='.$iso_code);
# Print out the language name and greeting
# Filter the greeting through gettext
printf ("<b>%12s:</b> %s/n", $language, _("Good morning!"));
}
?>
</pre>
If you encounter troubles with these examples, read the gettext documentation. While gettext is simple to use, it takes a bit of time to get the hang of it.