0 follower

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

Интернационализация (сокращённо I18N) — процесс создания приложения, которое может работать на различных языках и с различными региональными особенностями без каких либо дополнительных изменений. Для веб-приложений это особенно важно, так как пользователь может быть из любой точки мира.

Yii поддерживает интернационализацию на нескольких уровнях:

  • Предоставляет региональные данные для всех возможных языков и их вариаций.
  • Сервис для перевода сообщений и файлов.
  • Форматирование дат и чисел в зависимости от региональных настроек.

В последующих разделах мы рассмотрим перечисленные возможности более подробно.

1. Региональные настройки и язык

Региональные настройки — это набор параметров, задающих язык пользователя, страну и любые другие специальные настройки интерфейса. Обычно настройки определяются идентификатором, состоящем из языка и региона. К примеру, идентификатор en_US соответствует английскому языку и настройкам для США. В Yii все идентификаторы региональных настроек названы единообразно: LanguageID (язык) или LanguageID_RegionID (язык_регион) в нижнем регистре. Например: ru, en_us.

Региональные настройки хранятся в объекте класса CLocale, который можно использовать для получения зависимой от них информации, такой как символы и форматы валют и чисел, форматы дат и времени, название месяцев и дней недели. Так как информация о языке уже содержится в идентификаторе, в CLocale она не дублируется. По этой причине мы часто применяем в одном контексте термины «язык», «региональные настройки» и «локаль».

Имея идентификатор языка, мы можем получить соответствующий ему объект CLocale: CLocale::getInstance($localeID) или CApplication::getLocale($localeID).

Информация: в состав Yii включены региональные данные практически по всем языками и регионам. Данные получены из Common Locale Data Repository (CLDR). Доступны не все данные, предоставляемые CLDR, так как там содержится большое количество редко используемой информации.

В приложении Yii мы различаем язык приложения и исходный язык приложения. Язык приложения — это язык (локаль) пользователя, который работает с приложением. Исходный язык приложения — язык, который используется в исходном коде приложения. Интернационализация требуется только в том случае, если эти два языка различаются.

Вы можете установить язык приложения в настройках приложения или изменить его непосредственно перед использованием возможностей интернационализации.

Подсказка: Иногда нам требуется считать язык пользователя из браузера. Мы можем получить идентификатор локали используя CHttpRequest::preferredLanguage.

2. Перевод

Самой востребованой возможностью интернационализации, скорее всего, является перевод. Он включает в себя перевод сообщений и строк в представлениях. Первый используется для перевода отдельных сообщений, второй — для перевода файлов целиком.

В процессе перевода участвуют объект перевода, исходный язык и конечный язык. В Yii исходный язык по умолчанию приравнивается к исходному языку приложения, а язык к языку приложения. Если оба языка совпадают — перевод не производится.

Перевод сообщений

Перевод сообщений осуществляется при помощи метода Yii::t(). Метод переводит данное сообщение с исходного языка приложения на текущий язык приложения.

При переводе необходимо указать категорию сообщения, так как оно может иметь различные переводы в разных категориях (контекстах). Категория с именем yii является зарезервированной для использования ядром фреймворка.

Сообщения могут содержать параметры, которые при вызове Yii::t() заменяются соответствующими им значениями. К примеру, следующий вызов метода заменит {alias} на значение соответствующей переменной:

Yii::t('yii', 'Path alias "{alias}" is redefined.',
    array('{alias}'=>$alias))

Примечание: переводимые сообщения не должны содержать переменных, изменяющих строку ("Invalid {$message} content."). Если есть необходимость подставлять в строку какие-либо значения — используйте параметры.

Переведённые сообщения хранятся в репозитории, называемом источник сообщений. Источник сообщений представляет собой экземпляр класса CMessageSource или его наследника. При выполнении Yii::t() производится поиск сообщения в источнике сообщений и, если оно найдено — возвращается его переведённая версия.

Yii поддерживает несколько типов источников сообщений, перечисленных ниже. Также вы можете создать свой источник, отнаследовав его от CMessageSource.

  • CPhpMessageSource: переводы сообщений хранятся как пары ключ-значение в массиве PHP. Исходное сообщение при этом является ключом, а переведённое — значением. Каждый массив содержит переводы для определённой категории сообщений и находится в отдельном файле, имя которого совпадает с названием категории. Файлы с переводом для одного и того же языка хранятся в одной директории, имеющей такое же имя, как и идентификатор языка. Директории для всех языков располагаются в директории, указанной в basePath;

  • CGettextMessageSource: переводы сообщений хранятся в формате GNU Gettext;

  • CDbMessageSource: переводы сообщений хранятся в базе данных. Подробнее см. CDbMessageSource.

Источник сообщений загружается как компонент приложения. Сообщения, которые используются в приложении, хранятся в компоненте messages. По умолчанию тип данного источника сообщений — CPhpMessageSource. Путь, по которому хранятся файлы перевода — protected/messages.

Таким образом, для того, чтобы использовать механизм перевода сообщений, необходимо следующее:

  1. Вызвать Yii::t() в нужных местах;

  2. Создать файлы перевода protected/messages/IdЯзыка/ИмяКатегории.php. Каждый такой файл просто возвращает массив переведённых сообщений. Обратите внимание, что при этом используется CPhpMessageSource;

  3. В файле конфигурации установите значения CApplication::sourceLanguage и CApplication::language.

Подсказка: Если в качестве источника сообщений используется CPhpMessageSource, для работы с сообщениями может использоваться утилита yiic. При помощи команды message возможно выбрать из исходного кода все сообщения, для которых необходим перевод и, при необходимости, объединить их с уже существующим переводом.

Начиная с версии 1.0.2, в Yii добавлена поддержка формата выбора. Формат выбора предназначен для выбора перевода в зависимости от заданного числа. К примеру, в английском языке слово 'book' может быть единственного или множественного числа в зависимости от количества книг. В других языках слово может не иметь специальной формы (как в китайском) или может подчиняться более сложным правилам для множественного числа (как в русском). Формат выбора решает данную проблему простым, но в то же время эффективным способом.

Для использования формата выбора перевод должен содержать последовательность пар выражение-сообщение, разделённых символом |:

'expr1#message1|expr2#message2|expr3#message3'

где exprN — выражение PHP, возвращающее логическое значение. Если выражение равно true — используется соответствующий ему перевод и дальнейшие выражения не вычисляются. Выражение может содержать специальную переменную n (не $n!), которая содержит число, переданное первым параметром. Допустим, если мы используем перевод

'n==1#one book|n>1#many books'

и передаём число 2 параметром Yii::t(), то получим many books.

Если проверяется соответствие определённому числу, можно использовать сокращённую запись, которая будет рассматриваться как n==Number:

'1#one book|n>1#many books'

Перевод файлов

Перевод файлов осуществляется вызовом CApplication::findLocalizedFile(). Параметром передаётся путь к файлу, который необходимо перевести. Метод ищет одноимённый файл в подпапке LocaleID. Если файл найден — возвращается его путь, иначе — путь к исходному файлу.

Перевод файла используется в основном при отображении представлений. При вызове одного из методов отображения контроллера или виджета, файлы представления будут переведены автоматически. К примеру, если язык приложения установлен как zh_cn, а исходный язык как en_us — при отображении представления edit будет произведёт поиск представления protected/views/ControllerID/zh_cn/edit.php. Если оно найдено — будет использована переведённая версия, если нет — исходная, расположенная в protected/views/ControllerID/edit.php.

Перевод файлом можно использовать и для других целей. Например, для того, чтобы отобразить переведённое изображение или загрузить локализованную версию файла.

3. Форматирование даты и времени

Дата и время в разных странах и регионах часто форматируются по-разному. Задача форматирования даты и времени таким образом сводится к герерации строки, подходящей для данной страны и региона. Для этого в Yii используется CDateFormatter.

Каждый экземпляр CDateFormatter соответствует некому языку приложения. Чтобы получить форматтер для выбранного языка, мы можем просто обратиться к свойству приложения dateFormatter.

Класс CDateFormatter содержит два метода, предназначенных для форматирования UNIX timestamp:

  • format: форматирует переданную в формате UNIX timestamp дату согласно шаблону (например, $dateFormatter->format('dd.MM.yyyy', $timestamp));

  • formatDateTime: форматирует переданную в формате UNIX timestamp дату согласно шаблону, заданному для выбранного языка (например формат даты short, формат времени long).

4. Форматирование чисел

Также, как дата и время, числа могут писаться по-разному в разных странах и регионах. Форматирование чисел включает в себя форматирование десятичных дробей, валют и чисел с процентами. Для выполнения данных задач в Yii используется класс CNumberFormatter.

Для того, чтобы воспользоваться форматтером чисел, соответствующим выбранному языку, мы можем обратиться к свойству приложения numberFormatter.

Для форматирования целых чисел и дробей в классе CNumberFormatter есть следующие методы:

  • format: форматирует число в соответствии с заданным форматом (например, $numberFormatter->format('#,##0.00',$number));

  • formatDecimal: форматирует число в соответствии с форматом, заданным для текущего языка приложения;

  • formatCurrency: форматирует число и код валюты в соответствии с форматом, заданным для текущего языка приложения;

  • formatPercentage: форматирует число в соответствии с форматом форматирования процентов, заданным для текущего языка приложения.