Перевод проекта на использование транслитерации в заголовке

Миграция

Начать надо с того, что внедрить поле slug в таблицу базы данных. Самый лучший способ написать миграцию:

./yii migrate/create add_slug_to_TABLENAME

Сама миграция:

<?php
use yii\db\Migration;
class m180207_083817_add_slug_to_TABLENAME extends Migration { 
   public function safeUp() {
      $this->addColumn(
         '{{%TABLENAME}}',
         'slug',
         $this->string()->comment('SLUG'));
   }
   public function safeDown() {
      $this->dropColumn('{{%TABLENAME}}', 'slug');
   }
}

Запускаю миграцию:

./yii migrate

База данных подготовлена.

Изменяю модель

Свойство ‘attribute’ должно указывать на поле таблицы из которого будет формироваться slug.

<?php
   use yii\behaviors\SluggableBehavior;
// ...
class MODELNAME extends ActiveRecord
{
    // ...
          public function behaviors()
    {
        return [
            [
                'class' => SluggableBehavior::className(),
                'attribute' => 'title',
            ],
        ];
    }
    // ...
}

Теперь при создании или изменении записи, в поле slug автоматически будет записываться текст заголовка.

Изменения в контроллере

Добавляю метод

protected function findModelBySlug($slug)
{
    if (($model = MODELNAME::findOne(['slug' => $slug])) !== null) {
        return $model;
    } else {
        throw new NotFoundHttpException();
    }
}

Дальше надо изменить action

public function actionView($slug)
{
    return $this->render('view', [
        'model' => $this->findModelBySlug($slug),
    ]);
}

Теперь почти все готово. Но…

Нюанс с языком

Коробочный SluggableBehavior не работает с русскими буквами. Поэтому надо немного доработать.

Добавляю в composer.json:

"zabachok/yii2-sluggable-behavior": "*"

Затем обновляю проект:

composer update

И теперь в модели, вместо

use yii\behaviors\SluggableBehavior;

использую

use zabachok\behaviors\SluggableBehavior;

Так транслитерация работает как надо.

Завершающий этап

Теперь во всем приложении необходимо найти хелперы формирующие ссылки и заменить их на работающие со slug:

echo Url::to(['post/view', 'slug' => $post->slug]);