На момент написания этой заметке в системе ещё не реализован общий механизм поддержки нескольких языков, поэтому ниже будет рассмотрен пример реализации стандартными средствами yii. Перед прочтением рекомендуется ознакомиться со статьей в руководстве по yii.
1. Первое, что стоит сделать, это разобраться с маршрутизацией урлов.
Мы рассмотрим пример, когда текущий язык указывается в начале урла, например для русской версии новостей урл будет такой: /ru/news/
Для реализации такого поведения необходимо в конфиге переопределить дефолтный класс CUrlManager:
'urlManager'=>array( 'class'=>'application.components.PrUrlManager', 'languages'=>array('ru','en'), 'langParam'=>'lang', ),
Наш новый UrlManager будет базироваться на расширении LangUrlManager:
Yii::import('application.extensions.urlManager.LangUrlManager', true); class PrUrlManager extends LangUrlManager { protected function createUrlRule($route,$pattern) { $language = $this->languages; return parent::createUrlRule($route, "<".$this->langParam.":(".implode('|',$language).")>/".$pattern); } }
Здесь мы у всех зарегистрированных правил меняем роут - добавляем в начале новый параметр из языка. Т.о. все сгенерированные урлы будут идти с префиксом /en/ или /ru/
Всю остальную логику реализует расширение LangUrlManager.
2. Теперь разберемся с моделями. Для начала определяем в каких моделях необходимо переводить данные на другой язык. Например это могут быть Новости (поля Заголовок, Краткое содержание, Основной контент) и Меню (Заголовок, Название, Контент).
Для каждой модели необходимо создать новые поля. Например, для Новостей это будут title_en, short_en, content_en. "_en" на конце должно быть обязательно. И если в приложении используются и другие языки, например немецкий, то и для него надо создать соответствующие поля. Напомним, что в ygin поля автоматически создаются при создании свойств объекта.
3. Далее необходимо переопределить классы моделей. Рассмотрим в качестве примера Новости:
class PrNews extends News { private function getAttributeByLanguage($attr) { if (Yii::app()->language != 'ru') $attr .= '_'.Yii::app()->language; return $attr; } public function getTitle() { return $this->getAttributeByLanguage('title'); } public function getShort() { return $this->getAttributeByLanguage('short'); } public function getContent() { return $this->getAttributeByLanguage('content'); } }
Выше мы подменяем название полей в зависимости от текущего языка. Подробнее о том как переопределить системную модель читайте в другом разделе документации.
4. Теперь разберемся с админкой, чтоб для неё не применялась обработка маршурутов из п. 1.
По умолчанию админка использует настройки из проектного конфига project.php, и по необходимости его можно переопределить создав файл конфига backend.php:
$projectConfig = include dirname(__FILE__).'/project.php'; unset($projectConfig['components']['urlManager']); // приводим urlManager к значению по умолчанию return $projectConfig;
5. На этом внедрение мультиязычности на сайт можно считать законченным. При обращении к модели $news->title автоматически будет браться информация по текущему языку.
Вариант решения
'name' => array(
'en' => 'name_en'
),
'caption' => array(
'en' => 'caption_en'
),
'content' => array(
'en' => 'content_en'
)
);
{
if (Yii::app()->language != 'ru') {
if (in_array($name, array_keys($this->data))) {
return $this->{$this->data[$name][Yii::app()->language]};
}
}
return parent::__get($name);
}
Вызов $news->title будет всегда заруливать на getTitle().
Так будет происходить потому что нет у модели атрибута title. Ведь поля переименуются в title_ru