Pull to refresh

Локализация интерфейса сайта с использованием PHP, Smarty и Gettext

PHP *
Все началось с того, что к существующему сайту понадобилось добавить русскую локализацию. После того как я изучал в течение нескольких дней эту тему и наступил множественные грабли, я в конце-концов получил рабочий сайт. А теперь хочу поделиться рецептом многоязычной локализации.
Проверено и отработано на PHP 5.3.3 (Linux)/PHP 5.3.1 (Windows) + Smarty 3.0.7. В данном случае для существующего сайта на английском создавалась русскоязычная версия.
Я не провожу ликбеза на тему «как это работает» (он есть на phpclub), но предлагаю простую инструкцию и описание возможных проблем, с которыми я сталкивался во время реализации.

Итак,
  1. Качаем плагин Smarty Gettext (обязательно версии 1.0b1, а не 0.9.1, которую предлагают!): скачать, почитать больше про плагин (рекомендуется)
  2. Забираем оттуда файл block.t.php и кладем его в директорию smarty/plugins
  3. Создаем в корне сайта папку locale (можно и в другом месте, но только следите за путями), а в ней папку ru
  4. В папке ru создаем папку LC_MESSAGES — здесь будут храниться языковые файлы для русского языка
  5. После чего необходимо пройтись по всем файлам *.tpl и окружить все строки, которые должны быть переведены тэгом {t}, вот так:

    {t}Members{/t}
    {t 1=$user}Here is your payment for %1{/t}


    Пр формат тэга {t} можно почитать в документации к плагину Smarty Gettext
  6. Теперь, используя утилиту tsmarty2c.php из плагина Smarty Gettext, создается база строк, которую необходимо будет переводить на другие языки. Изначально предполагалось запускать утилиту из командной строки, передавая ей параметрами имена папок/файлов, но я предлагаю модифицированную версию, которая ищет *.tpl файлы в папке ./templates, парсит в них строк и кладет их в файл ./locale/langfrases.ctsmarty2c.phps
  7. Для создания языковых файлов я предлагаю использовать Poedit — кросс-платформенный редактор языковых файлов.
    В нем следует создать новый каталог (Файл-Создать каталог), указав на вкладке «Пути» путь к папке locale, в которой уже должен находиться файл langfrases.c (будьте осторожны — Poedit категорически не любит лишних пробелов в конце пути!). Каталог следует сохранить в папке LC_MESSAGES под именем messages.po. После чего редактор просканирует указанный путь на предмет файлов, содержащих строки и предложит их перевести:



    В результате после сохранения каталога в папке LC_MESSAGES у вас должны получиться два файла — messages.mo и messages.po, содержащие переводы строк на русский язык
  8. Теперь, когда у нас есть языковой файл с переводами строк, необходимо его подключить к сайту. Предположим, что имеется два языка — Английский и Русский. В этом случае используется две локали — 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", "");
    }
    
После этого, при входе на страницу, вместо строк, окруженных тэгом {t} будут показаны переведенные строки из языкового файла. Если же в языковом файле они отсутствуют, будет показан не измененный текст.

Проблемы, которые могут возникнуть:
  • Файл messages.mo в Windows кэшируется, и изменения в нем видны только после перезагрузки Apache.
  • Если передать функции setlocale значение отличное от LC_MESSAGES, то возможно возникновение проблем, связанных с тем, что в русском языке дробная часть отделяется запятой, а в английском — точкой. Так как локаль начинает влиять и на представления чисел в PHP, то при запросах к MySQL дробная часть теряется.
  • Локали ru_RU.utf8 и ru_RU могут отличаться на сервере. Если указывать просто ru_RU, то есть шанс получить вопросительные знаки вместо букв.
Осталась нерешенной проблема склонения существительных с числами и их множественного числа.
Утилита tsmarty2c умеет обрабатывать формы множественного числа и использовать вызовы ngettext, а вот Poedit у меня отказался их принимать.

Надеюсь, что этот топик поможет вам сэкономить свое время и подтолкнет к созданию еще лучших, качественных сайтов =)
Tags:
Hubs:
Total votes 42: ↑31 and ↓11 +20
Views 25K
Comments Comments 39