php-developers.net
Archive for the 'PHP' Category
Creating a multilingual site is a common task that can be simplified to a considerable amount if the right tools are used. One of the common ways to create a website in several languages is by using a set of GNU tools called Gettext. This article deals with the usage of Gettext and solves common multilingual tasks.
Requirements
You must have the Gettext extension enabled in php.ini
Using Gettext
1. Set up the Gettext environment
1.1. Define what language to use (in our case ‘bg’ stands for Bulgarian)
$language = ‘bg’;
1.2. Save it in the LANG environment variable
putenv(”LANG=$language”);
1.3. Set the current locale
setlocale(LC_ALL, $language);
1.4. Set the default domain
textdomain(’messages’);
1.5. Set the path for the domain ‘messages’
bindtextdomain(’messages’, ‘/path/to/locale/directory’);
1.6. Specify the character encoding in which the messages from the DOMAIN message catalog will be returned. For multilingual sites you would most likely use UTF-8
bind_textdomain_codeset(’messages’, ‘UTF-8′);
2. Usage in the php files is as simple as using the gettext function or the _()
echo gettext(”I bought a new car yesterday”);
… is same as …
echo _(”I bought a new car yesterday”);
… and the last step is to create the Gettext files.
3. Set up the Gettext files
3.1. Directory structure - a locale directory is expected where you will keep the files containing the translated strings:
/locale
/bg
/LC_MESSAGES
messages.po
messages.mo
Adding an additional language files would result in creating its own set of directories. For example:
/locale
/bg
/LC_MESSAGES
messages.po
messages.mo
/en
/LC_MESSAGES
messages.po
messages.mo
3.2. The file with the ‘po’ extension holds the human readable strings and their translation. Here is what it contains, broken to parts:
3.2.1. Some header messages that give information about the file and the project:
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR Free Software Foundation, Inc.
# FIRST AUTHOR, YEAR.
#
#, fuzzy
msgid “”
msgstr “”
“Project-Id-Version: PACKAGE VERSION\n”
“POT-Creation-Date: 2002-04-06 21:44-0500\n”
“PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n”
“Last-Translator: FULL NAME \n”
“Language-Team: LANGUAGE \n”
“MIME-Version: 1.0\n”
“Content-Type: text/plain; charset=CHARSET\n”
“Content-Transfer-Encoding: ENCODING\n”
3.2.2. The strings and their translation
For the messages.po file in the ‘bg’ directory
#: products.php:3
msgid “I bought a new car yesterday”
msgstr “Купих си нова кола вчера”
For the messages.po file in the ‘en’ directory
#: products.php:3
msgid “I bought a new car yesterday”
msgstr “I bought a new car yesterday”
Here are the explanations of these lines:
#: products.php:3 -> shows the file and the line number that contains the string
msgid “I bought a new car yesterday” -> this is the string to be translated
msgstr “Купих си нова кола вчера” -> this is the translation of the string
3.3. The file with the ‘mo’ extension is the binary format. We will talk about the generation of this file later on in this article.
4. Creating po files
Obviously adding by hand the strings to be translated is not very convenient. Gettext offers a convenient way to automatically extract the Gettext strings from the php files using the xgettext command
$ xgettext -n *.php
This would create a po file with the headers explained above and includes the strings to be translated.
5. Translate the strings in the po files. Convenient tools for doing this are:
For Linux - KBabel
For Windows - poEdit
6. Converting po files to mo files
Once you translated the files you need to turn them to binary files (’mo’ files) and copy them to the appropriate language directories. To do the conversion run the following command:
$ msgfmt messages.po
7. What do we do if you need to add some more strings to the pot files and if we need to update some strings? The most logical way is to merge the current pot file with the new pot file that contains the new strings. To do this in Gettext use the msgmerge command.
$ msgmerge products1.po products2.po –output-file=merged_products.po
8. Advanced usage of gettext
8.1. Using dynamic variables. What about if you want to use dynamic variables within the translated strings? The printf function comes in hand.
printf(gettext(”Hello, %s”), “Peter”);
And the po file will look like this:
#: products.php:7
msgid “Hello, %s”
msgstr “Здравей, %s”
8.2. Another issue is the plural version of the strings. Printf comes in hand again together with ngettext:
printf(ngettext(”%d car”, “%d cars”, 1), 1);
printf(ngettext(”%d car”, “%d cars”, 2), 2);
And the po file will look like this:
msgid “%d car”
msgid_plural “%d cars”
msgstr[0] “%d кола”
msgstr[1] “%d коли”
An important factor here is to add a header in the po file that defines the plural format for the specified language. The following example is specific to the English language. For other languages check the Gettext documentation:
“Plural-Forms: nplurals=2; plural=n != 1;\n”
Examples - source code
Here is an example from a shopping cart application with fully functioning Gettext examples. To install and run it just unzip it to a subdirectory in htdocs and run items.php.
Click here to download the attachment
Windows
Prerequisites :
PHP 5.2
Step 1 :
Download the progress upload extension from the PECL respository http://pecl4win.php.net/ext.php/php_uploadprogress.dll
Step 2 :
Copy php_uploadprogress.dll to the extension directory
Step 3 :
Add to php.ini
extension=php_uploadprogress.dll
Step 4 :
Add to php.ini
[uploadprogress]
uploadprogress.file.filename_template=”\path\to\tmp\sometext_%s.txt”
Step 5 :
Do not forget to restart your web server
Linux
Prerequisites :
PHP 5.2
Step 1 :
Download the uploadprogress extension from PECL: http://pecl.php.net/package/uploadprogress
Step 2 :
Enter in the directory you downloaded the extension to and run these commands as root:
phpize
./configure –enable-uploadprogress
make
make install
Step 3 :
Add this to php.ini:
extension=uploadprogress.so
Step 4 :
Restart your web server