Как стать автором
Обновить

Комментарии 30

> Долгожданный релиз Yii 2.0 Beta

Брр, релиз бета-версии?
Может я не внимательно прочитал, но не увидел как все-таки лучше организовать хранение самих текстов страниц на разных языках в базе данных. Вопрос более широкий и не касается конкретно Yii. Где по данной теме можно прочитать советы, какой подход наиболее правильный?
Ну раз уж написали вопрос к статье про Yii, отвечу касательно фреймворка. Взгляните как предлагается хранить это не на уровне файлов, а централизованно в БД.
Сомневался в добавлении этого в статью. Добавлю комментом. Обычно делаем через таблицу связей. Типичный пример для блога и постов.
Таблица post(модель Post) — храним метаинформацию, которая не имеет отношения к контенту. То есть такие поля: id, owner_id, date_create, date_update.
Таблица post_lang(модель PostLang) — связь контента по языкам. Поля: id, post_id, lang_id, name, description. Соответственно поля post_id — это id из таблицы post, lang_id — это id из таблицы lang. name и description — контент на соответствующем языке.
В модель Post добавляем отношение:

public function getContent($lang_id=null)
{
$lang_id = ($lang_id === null)? Lang::getCurrent()->id: $lang_id;

return $this->hasOne(PostLang::className(), ['post_id' => 'id'])->where('lang_id = :lang_id', [':lang_id' => $lang_id]);
}

Тогда в отображении, для текущего языка, контент можно получить так: $post->content->name; — заголовок поста, $post->content->description; — сам пост.
Или для контента на определенном языке, задав идентификатор языка($lang_id): $post->getContent($lang_id)->name; $post->getContent($lang_id)->description;
НЛО прилетело и опубликовало эту надпись здесь
Когда то давно делал мультиязычный проект на Yii1 + mysql, сделал составной PRIMARY KEY из полей id, lang и хранил для каждого языка запись, т.е. получалось 3 записи с одним id и разным lang, а в выборке указывал where lang = $lang AND id = $id, понимаю что не самый красивый подход, но на то время как придумал так и сделал :)
Спасибо, как раз надо было реализовать многоязычность при переписывание портала
В 1м Yii для определения языка в урле, пришлось переопределять метод removeUrlSuffix класса CUrlManager
Не самый лучший способ. Да и нелогичный.
А какой есть ещё способ?
Нелогичночность в том, что вы префиксы обрабатываете в методе, предназначенном для разруливания суффиксов. Я когда реализовывал схожий механизм, добавил метод removeUrlPrefix и вызывал его из перегруженного parseUrl. Правда это вынуждает нас копипастить код. Собственно это единственный плюс вашего подхода. У меня просто изменения довольно координальными были и кто-либо кроме меня не вжисть не догадался бы при таком раскладе где какая магия происходит. Правда когда пришлось треть класса переопределить, уже понял что это безнадежно и прилепил symfony/routing.
Пора!
Друг попросил откомментировать.
Юрий Шеховцов:
Для этого способа надо что-то делать с сабмитами.
Иначе в каждом определении формы надо явно указывать action.
Если этого не делать, префиксы ru-en не будут подставляться. createUrl() в сабмите не участвует.
Спасибо за вопрос. Действительно, createUrl — не участвует в формировании action в форме. Так же он не участвует в виджетах, например GridView. Для этого пришлось немного переписать класс LangRequest, и переопределить в нем resolvePathInfo, а не resolveRequestUri. Изменения коснулись только пункта «Определения языка» и «Виджет переключения языков»(сменить Yii::$app->getRequest()->getUrl() на Yii::$app->getRequest()->getLangUrl()). Изменения внес в статью. Теперь в формах и виджетах урлы формируются корректно.
А если мы переопределим метод resolveRequestUri:, то как на это отреагирует все, что это использует? да те же миграции, например?
1. а кто как относится к решению, где в качестве языка источника используются ключи?
сами же переводы располагаются в хранилище (например в базе данных). Плюс такого подхода в том, что в случае опечаток (или не совсем лаконичная фраза) в исходниках, переводчик может через админ интерфейс быстро перевести значение на самом сайте.
У вас 2 тезиса, на какой отвечать? :)

>> а кто как относится к решению, где в качестве языка источника используются ключи?

Имеятся в виду идентификаторы строк в БД? Думаю, это неудачное решение, потому что при редактировании будет очень сложно разобрать, где какой перевод. Лучше просто завести поле с уникальным ключом.

>> сами же переводы располагаются в хранилище (например в базе данных)

А это здравое решение, и многие (и мы) так и делают.
имелось в виду, на сколько жизнеспособна идея использовать в качестве sourceLanguage = 'key'?
например:
вместо того чтобы писать в коде Yii:t('app', 'ваша модель {model} не найдена потому что ...(длинный текст с опечатками)', ['model' => 'User']);
можно просто написать Yii:t('app', '{model} not_found', ['model' => 'User']);
А как можно сгенирировать URL с учетом языка?
Yii::$app->getRequest()->getLangUrl()

Выдает только \
//Для текущего языка
Yii::$app->urlManager->createUrl('/myurl', array('lang_id'=>Lang::getCurrent()->id));

//Для кастомного
$lang = Lang::find()->where('local = :local', [':local' => 'en-En'])->one();
Yii::$app->urlManager->createUrl('/myurl', array('lang_id'=>$lang->id));
Спасибо. Это мне помогло.
Изучаю вопрос, и наткнулся на расширение yii2-translate-manager. Релиз, вроде как, от вчера.

В силу неопытности не могу сказать стоит его «прикручивать» в рабочий проект. Код вроде солидный… Может кто посмотрит опытным глазом!?
дублируются классы Lang
Переименуйте класс виджета.
Спасибо! Поправил
А как правильно сделать такую вещь, чтобы при запросе example.com/mypage не просто грузился контент на языке по-умолчанию, а перекидывало на адрес example.com/ru/mypage (где ru — язык по-умолчанию). Чтобы не было дублирующихся страниц. Потому что, если не ошибаюсь, дублирующиеся страницы плохо сказываются на SEO.
мидлвэры спасут мир.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории