В Yii есть поддержка многоязычности, но она не касается контента. Контент, обычно, предлагается размещать раздельно. Фактически это разные сайты.
Для блога это не удобно. Проще проводить подстрочный перевод:
<p class='ru'> Текст на родном языке. </p> <p class='en'> Text in native language. </p>
Как видно, определены два класса: .ru
, .en
.
При текущем языке - ru-RU, отображаются html-теги с классом .ru
, а остальные, теги с классом .en
удаляются.
Если нажат переключатель языка, теги с классом .ru удаляются
, а .en
показываются.
В поля с "коротким" содержимым (например заголовк поста), языковые версии разделены символом "/".
Именно этот подход и реализован этим небольшим расширением, рассчитанным на поддержку двух языков.
В каталоге приложения:
$ composer require sergmoro1/yii2-lang-switcher "dev-master"
Зарегистрировать виджет в приложении - common/config/main.php
:
<?php return [ ... 'bootstrap' => [ 'LangSwitcher', ], ... 'modules' => [ 'langswitcher' => ['class' => 'sergmoro1\langswitcher\Module'], ], ... 'components' => [ 'LangSwitcher' => ['class' => 'sergmoro1\langswitcher\widgets\LangSwitcher'], ], ];
Вызвать виджет в frontend/views/layouts/main.php
или в ином layouts
:
... use sergmoro1\langswitcher\widgets\LangSwitcher; ... <body> <?= LangSwitcher::widget(); ?>
В меню или любом подходящем месте разместить переключатель:
<?php echo Html::a('rus|eng', ['langswitcher/language/switch']); ?>
В модели нужно предусмотреть выборку данных, соответствующих текущему языку. Для этого нужно подключить поведение.
public function behaviors() { return [ 'LangSwitcher' => ['class' => LangSwitcher::className()], ]; }
Теперь в представлении frontend/views/post/view.php
можно вывести контент следующим образом
<?= $model->excludeByLanguage('content'); ?>
а заголовок поста так.
<?= $model->splitByLanguage('title'); ?>
Чтобы данные выводились единообразно, в том числе в RSS, нужно в модели common/models/Post.php
определить метод fields
public function fields() { return [ 'id', 'author_id', 'slug', 'title' => function ($model) { return $model->splitByLanguage('title'); }, 'content' => function ($model) { return $model->excludeByLanguage('content'); }, 'tags', 'status', 'created_at', 'updated_at', ]; }Чтобы применить предложенный подход к статичным страницам, нужно пропустить контент через фильтр
excludeByLanguage()
.
Для этого нужно, чтобы frontend/controllers/SiteController
наследовался от контроллера, определенного в расширении.
use sergmoro1\langswitcher\controllers\Controller;class SiteController extends Controller {
Помните, что в sitemap
тоже надо учитывать языковую версию.