Все началось с того, что к существующему сайту понадобилось добавить русскую локализацию. После того как я изучал в течение нескольких дней эту тему и наступил множественные грабли, я в конце-концов получил рабочий сайт. А теперь хочу поделиться рецептом многоязычной локализации.
Проверено и отработано на PHP 5.3.3 (Linux)/PHP 5.3.1 (Windows) + Smarty 3.0.7. В данном случае для существующего сайта на английском создавалась русскоязычная версия.
Я не провожу ликбеза на тему «как это работает» (он есть на phpclub), но предлагаю простую инструкцию и описание возможных проблем, с которыми я сталкивался во время реализации.
Итак,
Проблемы, которые могут возникнуть:
Утилита tsmarty2c умеет обрабатывать формы множественного числа и использовать вызовы ngettext, а вот Poedit у меня отказался их принимать.
Надеюсь, что этот топик поможет вам сэкономить свое время и подтолкнет к созданию еще лучших, качественных сайтов =)
Проверено и отработано на PHP 5.3.3 (Linux)/PHP 5.3.1 (Windows) + Smarty 3.0.7. В данном случае для существующего сайта на английском создавалась русскоязычная версия.
Я не провожу ликбеза на тему «как это работает» (он есть на phpclub), но предлагаю простую инструкцию и описание возможных проблем, с которыми я сталкивался во время реализации.
Итак,
- Качаем плагин Smarty Gettext (обязательно версии 1.0b1, а не 0.9.1, которую предлагают!): скачать, почитать больше про плагин (рекомендуется)
- Забираем оттуда файл block.t.php и кладем его в директорию smarty/plugins
- Создаем в корне сайта папку locale (можно и в другом месте, но только следите за путями), а в ней папку ru
- В папке ru создаем папку LC_MESSAGES — здесь будут храниться языковые файлы для русского языка
- После чего необходимо пройтись по всем файлам *.tpl и окружить все строки, которые должны быть переведены тэгом {t}, вот так:
{t}Members{/t}
{t 1=$user}Here is your payment for %1{/t}
Пр формат тэга {t} можно почитать в документации к плагину Smarty Gettext
- Теперь, используя утилиту tsmarty2c.php из плагина Smarty Gettext, создается база строк, которую необходимо будет переводить на другие языки. Изначально предполагалось запускать утилиту из командной строки, передавая ей параметрами имена папок/файлов, но я предлагаю модифицированную версию, которая ищет *.tpl файлы в папке ./templates, парсит в них строк и кладет их в файл ./locale/langfrases.c — tsmarty2c.phps
- Для создания языковых файлов я предлагаю использовать Poedit — кросс-платформенный редактор языковых файлов.
В нем следует создать новый каталог (Файл-Создать каталог), указав на вкладке «Пути» путь к папке locale, в которой уже должен находиться файл langfrases.c (будьте осторожны — Poedit категорически не любит лишних пробелов в конце пути!). Каталог следует сохранить в папке LC_MESSAGES под именем messages.po. После чего редактор просканирует указанный путь на предмет файлов, содержащих строки и предложит их перевести:
В результате после сохранения каталога в папке LC_MESSAGES у вас должны получиться два файла — messages.mo и messages.po, содержащие переводы строк на русский язык - Теперь, когда у нас есть языковой файл с переводами строк, необходимо его подключить к сайту. Предположим, что имеется два языка — Английский и Русский. В этом случае используется две локали — en_US и ru_RU.utf8. Для того, чтобы использовать его в PHP нам понадобится следующий код (скачать):
$lang = 'ru_RU.utf8'; if (!defined('LC_MESSAGES')) define('LC_MESSAGES', 5); // в Windows эта константа может быть не определена setlocale(LC_MESSAGES, $lang); // устанавливаем локаль if (!isset ($_COOKIE['lang'])) setcookie('lang', $lang, 1640995200); // сохраняем язык в Cookie bind_textdomain_codeset("messages", 'UTF8'); // устанавливаем кодировку файла messages.mo if ($lang == 'ru_RU.utf8') { // подключаем файлы русской локализации bindtextdomain("messages", "./locale"); textdomain("messages"); } else { // возвращаем английский язык bindtextdomain("messages", ""); }
Проблемы, которые могут возникнуть:
- Файл messages.mo в Windows кэшируется, и изменения в нем видны только после перезагрузки Apache.
- Если передать функции setlocale значение отличное от LC_MESSAGES, то возможно возникновение проблем, связанных с тем, что в русском языке дробная часть отделяется запятой, а в английском — точкой. Так как локаль начинает влиять и на представления чисел в PHP, то при запросах к MySQL дробная часть теряется.
- Локали ru_RU.utf8 и ru_RU могут отличаться на сервере. Если указывать просто ru_RU, то есть шанс получить вопросительные знаки вместо букв.
Утилита tsmarty2c умеет обрабатывать формы множественного числа и использовать вызовы ngettext, а вот Poedit у меня отказался их принимать.
Надеюсь, что этот топик поможет вам сэкономить свое время и подтолкнет к созданию еще лучших, качественных сайтов =)