Gettext() for PHP tutorial

This is a quick tutorial on how to use gettext() to internationalize your PHP application. In this case we will use the example of Ofuz internationalization.

Installing Gettext()

This is an example as in Debian or Ubuntu

 sudo apt-get install gettext
 
 

Now depending on which language you plan to translate to and from you need all of the to be installed. You can install more language with the following:

 sudo dpkg-reconfigure locales 
 

Generating the message file

Once gettext is install you can extract from your source code all the strings with _() they will be the base message for all translations.

xgettext -o locale/en_US.utf8/LC_MESSAGES/messages.po $(find . -name “*.php”)

Do not copy the above command directly to the terminal make sure about the double quotes.

Once the messages.po file is created, the header of the file looks like below and if the charset is not UTF-8 please make it UTF-8

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-08-25 07:54-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

Now we have a messages.po which is human readable we need to create a messages.mo that will be indexed and used by the gettext library.

Now we can create a .mo file as below

     msgfmt locale/en_US.utf8/LC_MESSAGES/messages.po -o locale/en_US.utf8/LC_MESSAGES/messages.mo

Directory structure

This is the hard part, gettext is very difficult with the folder structure. It needs to be exactly as described or it will just not load the files.

The domain define the path.

To store the language files the directory is locale

And Our different language files will be inside this directory.

Say we want to have 2 languages English and French for Ofuz.

we will create two directory as

en_US and fr_FR inside the locale directory.

You will find the proper locale name for your language here: locales_list

In both of the above created directory we need to have another directory called LC_MESSAGES

The .mo and .po files for the translation would be inside this directory.

       /locale/en_US.utf8/LC_MESSAGES/messages.mo
                                     /messages.po
              /fr_FR.utf8/LC_MESSAGES/messages.po
                                     /messages.mo
                                

In the directory structure and file naming above the only things you can change is the language name, (en_US or fr_FR) and the language files, (messages.mo or messages.po). Language file must all have the same name.

Translating

Copy the /locale/en_US.utf8/LC_MESSAGES/messages.po in your own language folder in our example french

 
  cp en_US.utf8/LC_MESSAGES/messages.po fr_FR.utf8/LC_MESSAGES/messages.po
  

The messages.po file is human readable, you can open it in a text editor and start translating.

For example:

#: invoice.php:149 invoice.php:331 settings_auto_responder_email_edit.php:169
#: class/block/PaymentLogBlock.class.php:46 invoices_unpaid.php:150
msgid "Cancel"
msgstr ""
 
#: invoice.php:152 class/block/PaymentLogBlock.class.php:49
msgid "Add payment "
msgstr ""

Would translate to:

#: invoice.php:149 invoice.php:331 settings_auto_responder_email_edit.php:169
#: class/block/PaymentLogBlock.class.php:46 invoices_unpaid.php:150
msgid "Cancel"
msgstr "Annuller"
 
#: invoice.php:152 class/block/PaymentLogBlock.class.php:49
msgid "Add payment "
msgstr "Ajouter un payment"

You can find a number of application on the web that will help you with the translation strings.

There is even one that will translate the messages.po file for you using Google translate:

http://pepipopum.dixo.net/

Use the above URL to translate the file to French and then copy it to the directory

locale/fr_FR.utf8/LC_MESSAGES/

Once your messages.po file is translated you can generate the messages.mo file:

   msgfmt locale/fr_FR.utf8/LC_MESSAGES/messages.po -o locale/fr_FR.utf8/LC_MESSAGES/messages.mo

please make sure once u generate the .po on en_US the header should have “Content-Type: text/plain; charset=UTF-8\n”

Thats it the language file are ready.

Setup in your application

Before we create those files for the translation we need to ensure that the file

In Ofuz we have 1 configuration file and an other with the function call.

In the configuration file includes/i18n.conf.inc.php we have all the variables:

 
    $GLOBALS['cfg_lang'] = "en_US"; 
    $GLOBALS['cfg_charset'] = "utf8";
    $GLOBALS['cfg_language_app'] = "ofuz";
    $GLOBALS['cfg_locale_path'] = "locale/";
    $GLOBALS['cfg_language_file'] = "messages";

Change $GLOBALS['cfg_lang'] from en_US to fr_FR and it will all be in french.

Then in the includes/i18n_function.inc.php we have

 
        setlocale(LC_MESSAGES,$GLOBALS['cfg_lang'].".".$GLOBALS['cfg_charset']);
        putenv("LANG=".$GLOBALS['cfg_lang'].".".$GLOBALS['cfg_charset']);
        putenv("LANGUAGE=".$GLOBALS['cfg_lang'].".".$GLOBALS['cfg_charset']);
        setlocale(LC_ALL, $GLOBALS['cfg_lang'].".".$GLOBALS['cfg_charset']);
        //Required only if locale is not on the web root.
 
        bindtextdomain($GLOBALS['cfg_language_file'], dirname($_SERVER["SCRIPT_FILENAME"])."/".$GLOBALS['cfg_locale_path']);
        textdomain($GLOBALS['cfg_language_file']);
 
i18n/translating_with_gettext.txt · Last modified: 2010/11/27 16:30 by philippe
 
Copyright © SQLFusion LLC all rights reserved