Я использую сдедующий подход:
1) В базе данных информация о страницах (или товарах, или других сущностях) хранится в двух таблицах: например,
page и
page_content. Первая таблица - это данные, которые не требуют перевода (например id, дата создания, дата обновления, слаг итд.). Вторая таблица - это текстовые данные, которые будут мультиязычными (meta_title, meta_description, meta_keywords, content). Во второй таблице (с контентом), должно быть поле для связи с первой таблицой (напр. поле
page_id), а также поле для указания кода языка. Получается, что для одной записи в первой таблице существует несколько записей во второй таблице, каждая из которых - на разных языках.
2) В моделях нужно прописать связь один к одному для этих таблиц, в которых связующими будут поля по ID и по полю языка (параметр берётся из настроек приложения Yii::$app->language):
public function getPageContent()
{
return $this->hasOne(PageContent::className(), ['page_id' => 'id'])->andWhere(['page_content.language_code' => Yii::$app->language]);
}
Теперь при выборке данных из первой таблицы, будут подтягиваться тексты из второй таблицы, на текущем языке приложения.
3) Для управления текущим языком приложения и удобного переключения с одного языка на другой (параметр языка хранится в ссылке), существует замечательный компонент
Yii2 Locale URLs