воскресенье, 25 сентября 2011 г.

Интернационализация (сокращённо I18N). Мультиязычность.

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

Я еще только начал в этом разбираться, самого переключения языков еще нет, язык пока переключаю в конфигах сайта при помощи переменных 'sourceLanguage' и 'language', но обо всем по порядку.
В нашем любимом фреймворке мультиязычность, или интернационализация заложена изначально. Есть статьи в рецептах Интернационализация
и Мультиязычные модели
В файле Z:\home\catalog.loc\www\protected\config\main.php я добавил переменные, о которых уже говорил:
return array(
'defaultController'=>'assortiment',
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
'name'=>'Каталог. Мой первый сайт на Yii.',
'sourceLanguage' => 'en_US',
'language' => 'ru',
sourceLanguage – это язык, на котором сайт написан изначально. У меня это английский. Все названия меню, лейблы к таблицам у меня на английском.

Language – это значения языка, который хочет пользователь. Если значения этих переменных совпадает, то никакого перевода не происходит.
Сразу после добавления этих переменных, вернее элементов массива, сообщения сайта и сообщения в элементах zii (в zii.widgets.grid.CGridView например) стали на русском языке! Потому, что в папке фреймворка Z:\home\catalog.loc\www\protected\framework\messages уже есть перевод на русский (и еще на 31 других языков).
Теперь надо перевести собственные тексты сайта. Делается это так: в папке Z:\home\catalog.loc\www\protected\messages создаются папки тех языков, которые мы собираемся предложить пользователям, (называются эти папки по названию языка в госте ISO 639-1 ) то есть двухбуквенное обозначение. В созданной папке, например Z:\home\catalog.loc\www\protected\messages\ru я создал файл main-ui.php в нем и будет храниться весь перевод моих сообщений и текстов. Формат файла такой:
<?php
return array(
'Description' => 'Описание',
'Category' => 'Категория',
'Rating' => 'Рейтинг',
'Show in catalog?'=>'Показывать в каталоге?',
'Image'=>'Фотография',
'Delete image?'=>'Удалить фотографию?',
'Id'=>'№',
'Name'=>'Название',
'yes'=>'да',
'no'=>'нет',
'Manage Category'=>'Управление категориями',
'Manage Assortiment'=>'Управление товарами',
'Manage Pages'=>'Управление страницами',
'Manage Messages'=>'Управление сообщениями',
'Manage Page_Messages'=>'Управление содержанием страниц',
'Main operations'=>'Основные действия',
'Operations'=>'Действия',
'Manage'=>'Управление',
'Assortiments'=>'Товары',
'List Assortiment'=>'Список товаров',
'Create Assortiment'=>'Создать товар',
'You may optionally enter a comparison operator 
(<b>&lt;</b>, <b>&lt;=<
/b>, <b>&gt;</b>, <b>&gt;=
</b>, <b>&lt;&gt;</b> or <b>=</b>) at the 
beginning of each of your search values to specify how the comparison should be 
done.'=>'В поиске по колонкам, вы можете использовать операции 
сравнения: (<b>&lt;</b>, <b>&lt;=
</b>, <b>&gt;</b>, <b>&gt;=</b>, <b>&lt;&gt;</b> или <b>=</b>) 
знак сравнения ставится первым',
 'Advanced Search'=>'Расширенный поиск',
);
?> 
Теперь там, где раньше выводился просто текст, вывожу такую конструкцию:
 echo Yii::t('main-ui', 'Text in english');
'main-ui' это название файла перевода в папке Z:\home\catalog.loc\www\protected\messages\ru, а 'Text in english' это сообщение, которое будет выведено без изменений на английском, а на русском будет заменено переводом из файла.

Например: все лейблы к полям моделей я изменил так:
/**
* —return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(

'id' => Yii::t('main-ui', 'Id'),
'name' => Yii::t('main-ui', 'Name'),
'description' => Yii::t('main-ui', 'Description'),
'shown' => Yii::t('main-ui', 'Show in catalog?'),
'icon' => Yii::t('main-ui', 'Image'),
'del_img'=>Yii::t('main-ui', 'Delete image?'),
);
}
Я не буду описывать, какие именно строки, и в каких файлах я менял, потому, что это будет долго и нудно, просто приведу еще один пример:
Файл Z:\home\catalog.loc\www\protected\views\assortiment\admin.php несколько первых строк кода:

<?php
$this->breadcrumbs=array(
Yii::t('main-ui', 'Assortiments')=>array('index'),
Yii::t('main-ui', 'Manage'),
);

$this->menu=array(
array('label'=>Yii::t('main-ui', 'List Assortiment'), 'url'=>array('index')),
array('label'=>Yii::t('main-ui', 'Create Assortiment'), 'url'=>array('create')),
);
Ну, вот, сайт стал русскоязычным, осталось сделать переключение языков и добавить многоязычность непосредственно в таблицы. Продолжение следует.

11 комментариев:

  1. Автор, замечательная статья, спасибо тебе огромное! Я тоже начинаю работать с yii, твой опыт открыл мне глаза на многие моменты!

    ОтветитьУдалить
  2. Привет. Я так и не смог понять как ты делаешь запросы в базу с учетом языка и как ты выводишь данные, мне необходимо реализовать i18n на сайте, ты бы мог мне помочь с этим вопросом, вроде понятно, но до конца не разберусь никак, а на твоем тестовом сайте вроде работает все. Если ты не против, давай свяжемся по эл почте krvdns@mail.ru. Очень надеюсь на твою помощь.

    ОтветитьУдалить
    Ответы
    1. Разобрались в личной переписке.

      Удалить
  3. ne
    \home\catalog.loc\www\protected\framework\messages
    a
    \home\catalog.loc\www\framework\messages

    ОтветитьУдалить
  4. eshe u tebya tut rss i google adwords krivo otobrajayustsya v google chrome.

    i eshe est koe kakie voprosi pro yii v obshem. давай свяжемся по эл почте dr_ceferov@mail.ru.

    dobav v agent esli mojesh

    sps

    ОтветитьУдалить
  5. Спасибо! Годная статья! Заработало на ура! )

    ОтветитьУдалить
  6. Спасибо, сдвинулся с мертвой точки!

    ОтветитьУдалить
  7. интересно а если тебя надо добавить еще один язык то что ты будешь делать? ;)

    ОтветитьУдалить
    Ответы
    1. Надо просто создать еще один файл в Z:\home\catalog.loc\www\protected\messages\_название_языка_в_ISO 639-1\main-ui.php и переменной language давать значение этого языка.

      Удалить