Skip to content

Latest commit

 

History

History
executable file
·
112 lines (93 loc) · 4.27 KB

README_RU.md

File metadata and controls

executable file
·
112 lines (93 loc) · 4.27 KB

Yii2 переключатель языка

В 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 тоже надо учитывать языковую версию.