Localization of the site interface using PHP, Smarty and Gettext
It all started with the fact that the existing site needed to add Russian localization. After I studied this topic for several days and came up with multiple rakes, I finally got a working site. And now I want to share a recipe for multilingual localization. Tested and tested for PHP 5.3.3 (Linux) / PHP 5.3.1 (Windows) + Smarty 3.0.7. In this case, a Russian version was created for the existing site in English. I do not spend educational program on the topic of "how it works" (it is on phpclub ), but I offer a simple instruction and description of possible problems that I encountered during the implementation. So,
Now, using the tsmarty2c.php utility from the Smarty Gettext plugin, a database of strings is created that will need to be translated into other languages. It was originally intended to run the utility from the command line, passing folder / file names to it with parameters, but I suggest a modified version that looks for * .tpl files in the ./templates folder, parses the lines in them and puts them in the ./locale/langfrases.c file - tsmarty2c.phps
To create language files, I suggest using Poedit , the cross-platform editor of language files. In it, you should create a new directory (File-Create Directory), specifying the path to the locale folder in the Paths tab, which should already contain the langfrases.c file (be careful - Poedit absolutely does not like the extra spaces at the end of the path!). The directory should be saved in the LC_MESSAGES folder as messages.po . Then the editor will scan the specified path for files containing strings and offer to translate them:
')
As a result, after saving the directory in the LC_MESSAGES folder, you should have two files - messages.mo and messages.po , containing line breaks into Russian
Now that we have a language file with newlines, we need to connect it to the site. Suppose that there are two languages - English and Russian. In this case, two locales are used - en_US and ru_RU.utf8 . In order to use it in PHP, we need the following code ( download ):
$ lang = 'en_US.utf8';
if (! defined ('LC_MESSAGES')) define ('LC_MESSAGES', 5); // on Windows, this constant may not be defined
setlocale (LC_MESSAGES, $ lang); // set the locale
if (! isset ($ _COOKIE ['lang'])) setcookie ('lang', $ lang, 1640995200); // save the language to the cookie
bind_textdomain_codeset ("messages", 'UTF8'); // set the encoding of the file messages.mo
if ($ lang == 'en_US.utf8') {
// we connect files of Russian localization
bindtextdomain ("messages", "./locale");
textdomain ("messages");
}
else {
// return English
bindtextdomain ("messages", "");
}
After that, at the entrance to the page, instead of the lines surrounded by the {t} tag, the translated lines from the language file will be shown. If they are absent in the language file, unchanged text will be shown.
Problems that may arise:
The file messages.mo in Windows is cached, and changes in it are visible only after restarting Apache.
If you pass a value other than LC_MESSAGES to the setlocale function, you may experience problems related to the fact that in Russian the fractional part is separated by a comma, and in English - by a dot. Since the locale begins to influence the presentation of numbers in PHP, when querying MySQL, the fractional part is lost.
Locals ru_RU.utf8 and ru_RU may differ on the server. If you just specify ru_RU, then there is a chance to get question marks instead of letters.
The problem of the declension of nouns with numbers and their plural number remained unsolved. The tsmarty2c utility can handle plurals and use ngettext calls, but Poedit has refused to accept them.
I hope that this topic will help you save your time and encourage you to create even better, high-quality sites =)