Контент


Интернационализация приложения

Добрый день, %username%! Сегодня я предлагаю обратить внимание на предоставленную нам возможность легко «переводить» свои проекты на другие языки народов мира. Например, официальный сайт Kohana и его зеркала имеют один исходный код, но интерфейсные заголовки и надписи сделаны на различных языках. Давайте посмотрим, как это делается.

Ресурсы

Очевидно, что версии одного и того же сайта на разных языках будут отличаться только отдельными строковыми значениями (надписи на кнопках, системные предупреждения и т.д.). Эти сообщения часто называют ресурсами. Идея в том, чтобы выносить эти ресурсы из кода приложения (в частности, из Views) в текстовые файлы, чтобы облегчить перевод на другие языки. Наверняка вы видели в файловой структуре фреймворка директории с не очень понятным названием i18n. Именно там эти самые ресурсы и хранятся.

Справка:
Термин i18n образован от слова internationalization, причем 18 — количество символов между первой и последней буквой этого слова. Т.е. по сути i18n это просто аббревиатура. Кстати, аналогично L10n образован от localization.

Например, если вы скачали дистрибутив Kohana с поддержкой великого и могучего языка (соответствующая галочка на странице download), то увидите в папке system/i18n две директории: en_US и ru_RU. Имя директории состоит из двух двухсимвольных слов, разделенных знаком подчеркивания. Первое слово — код языка (список кодов из Wikipedia), второе — географический код (список). Т.е. en_US означает английский язык (en = english) на территории США (US = USA), или просто «американский английский». Теоретически en_US может отличаться от en_GB (GB = Great Britain), хотя на практике такое встречается редко.

Внутри каждой из таких директорий расположены файлы ресурсов. Например, в файле database.php для русского языка используются такие ресурсы:

<?php defined('SYSPATH') OR die('No direct access allowed.');
 
$lang = array
(
	'undefined_group'       => 'Группа %s не определена Вашей конфигурацией.',
	'error'                 => 'Ошибка SQL: %s',
	'connection'            => 'Не удалось подключиться к базе данных: %s',
	'invalid_dsn'           => 'Переданный DSN некорректен: %s',
	'must_use_set'          => 'Необходимо использовать оператор SET в этом запросе.',
	'must_use_where'        => 'Необходимо использовать оператор WHERE в этом запросе.',
	'must_use_table'        => 'Необходимо указать таблицу базы данных в этом запросе.',
	'table_not_found'       => 'Таблица %s не существует в Вашей базе данных.',
	'not_implemented'       => 'Запрошенный метод, %s, не поддерживается этим драйвером.',
	'result_read_only'      => 'Результат запроса доступен только для чтения.'
);

Как мы видим, каждый ресурс имеет свой ключевой идентификатор (например, ‘invalid_dsn‘) и собственно расшифровку. Доступ к ресурсу осуществляется с помощью функции Kohana::lang(). В качестве параметра передается идентификатор ресурса, состоящий из имени i18n-файла (например, ‘orm‘ или ‘database‘) и ключевого идентификатора ресурса в данном файле. Таким образом, чтобы получить ресурс ‘error‘ в файле ‘database.php‘, достаточно вызвать Kohana::lang(‘database.error’). Если ресурс не найден, будет возвращена строка с именем ресурса.

Вы наверное обратили внимание, что некоторые ресурсы содержат слова ‘%s‘ в теле строки. Дело в том, что есть возможность в качестве дополнительного параметра передавать массив строк для подстановки в ресурс. Например, Kohana::lang(‘database.error’, $this->db->show_error()) подставит в соответствующем ресурсе описание ошибки MySQL вместо ‘%s‘. Доступное форматирование можно посмотреть в описании функции sprintf(), которая используется фреймворком для формирования ресурсной строки.

Выбор языка

Изначально для указания «родного» для приложения языка служит файл config/locale.php, в котором указывается язык (параметр ‘language‘) и временная зона (параметр ‘timezone‘), например:

<?php defined('SYSPATH') OR die('No direct access allowed.');
 
$config['language'] = array('ru_RU', 'Russian_Russia');
 
$config['timezone'] = 'Europe/Moscow';

В локали можно указывать несколько значений, они будут перебраны по порядку, пока одна из локалей не подойдет. Например, при тестировании в домашних условиях в ОС Windows наверняка локаль ‘ru_RU’ (стандарт в *NIX-системах) не будет установлена. Подробнее можно посмотреть в документации по функции setlocale().
Временную зону можно не указывать — тогда будет использовано серверное время.

В дальнейшем выбранную локаль можно узнать с помощью функции Kohana::config():

echo Kohana::config('locale.language.0')

Конечно, необходимо предоставить пользователю возможность выбрать язык. К сожалению, текущая версия фреймворка (2.3.2) не поддерживает многоязычность в роутинге, но уже поступили предложения по ее реализации в виде дополнительного модуля (ticket, модуль в проектах Kohana), и он ожидается как официальный модуль в составе Kohana 2.4. Также можно поучаствовать в обсуждении этого модуля на форуме.

Применение

Если вы хотите создать i18n-приложение, привыкайте вместо того, чтобы вбивать в код шаблонов (интерфейсные надписи) и контроллеров (тексты ошибок) строки на конкретном языке, использовать Kohana::lang(). Я обычно пишу кусок кода (метод контроллера или шаблон), а затем собираю используемые там ресурсы в i18n-файлы.

Что же можно выносить в ресурсы?

  • Надписи в шаблоне — кнопки, менюшки и т.д.
  • Тексты ошибок и сообщений (в контроллерах).
  • Если есть картинки/скрипты, также требующие перевода, можно выносить в lang-файлы пути к ним, хотя мне кажется, что это не лучший вариант (например, можно в папках со статическими элементами также предусмотреть различные подпапки для языков).

Ну и напоследок пара советов:

  • Не бросайтесь параллельно вести несколько i18n-подпапок — запутаетесь и обязательно что-нибудь забудете перевести. Используйте один язык, а потом просто скопируете полученные файлы в другие папки и переведете.
  • Группируйте ресурсы в тематические файлы, как это уже сделано в дистрибутиве фреймворка. Называйте ключи ресурсов так, чтобы при чтении передаваемой строки в функцию lang() сразу можно было понять, что ожидается в результате.
  • Любые изменения в одном из lang-файлов обязательно надо синхронизировать с другими языками, иначе можно получить на сайте не очень приятные надписи типа ‘error.new_error‘. Например, в русском и немецком зеркалах официального сайта Kohana до сих пор не добавили перевод ключа ‘layout.menu_projects‘. ;)

Вот вроде бы и все. Успехов в построении i18n-проектов!

Update. Судя по всему, в версии 2.4 будет использоваться другой принцип перевода проектов. Подробнее можно почитать тут.

Google Bookmarks Digg Reddit del.icio.us Ma.gnolia Technorati Slashdot Yahoo My Web News2.ru БобрДобр.ru RUmarkz Ваау! Memori.ru rucity.com МоёМесто.ru Mister Wong

Опубликовано в cправочник.

Теги: , , .


Комментарии (0)

Будьте в курсе обсуждения, подпишитесь на RSS ленту комментариев к этой записи.



Можно включить подсветку кода: <code><pre lang="">...</pre></code>
Разрешены некоторые HTML теги

или используйте trackback.