Nuno Maduro презентував Laravel Sluggable — пакет для автоматичної генерації slug в моделях Eloquent. Замість використання трейтів чи базових класів, рішення пропонує один PHP-атрибут #[Sluggable], який додається безпосередньо до моделі.
Окрім базових функцій, пакет розв'язує складні завдання: обробку колізій, унікальність у межах певної області (per-tenant або per-locale), генерацію з кількох колонок, роботу з Soft Deletes, а також повну підтримку Unicode та транслітерацію CJK.
# З чого почати
Встановіть пакет через Composer:
composer require nunomaduro/laravel-sluggable
Примітка: Пакет потребує PHP 8.5+ та Laravel 13.5+
Найшвидший спосіб налаштувати модель — скористатися командою Artisan make:sluggable:
php artisan make:sluggable Post
Вона проаналізує схему таблиці, обере найбільш підходящу колонку-джерело (title, name, headline або subject), додасть атрибут #[Sluggable] до моделі та створить міграцію в database/migrations:
use NunoMaduro\LaravelSluggable\Attributes\Sluggable;
#[Sluggable(from: 'title')]
class Post extends Model
{
}
Schema::table('posts', function (Blueprint $table) {
$table
->string('slug')
// ->nullable()
->unique()
->after('id');
});
Перевірте міграцію перед запуском. Якщо в таблиці вже є дані, варто зробити колонку nullable перед виконанням php artisan migrate.
Після цього генерація slug відбуватиметься автоматично:
$post = Post::create(['title' => 'Laravel News Rocks']);
$post->slug; // "laravel-news-rocks"
# Налаштування
Усі опції вказуються в самому атрибуті. Параметри from та to визначають, які колонки використовувати для читання та запису. from також приймає масив, якщо потрібно об'єднати кілька полів:
#[Sluggable(from: ['first_name', 'last_name'], to: 'slug')]
class Author extends Model {}
$author = Author::create(['first_name' => 'John', 'last_name' => 'Tolkien']);
$author->slug; // "john-tolkien"
Для мультитенентних застосунків або забезпечення унікальності в межах групи додайте параметр scope:
#[Sluggable(from: 'title', scope: 'team_id')]
Інші корисні параметри: maxLength для обмеження довжини, separator для зміни розділювача та onUpdating для оновлення slug при зміні джерела. За замовчуванням slug фіксується після створення, а ручні зміни завжди зберігаються незалежно від налаштувань.
# Обробка помилок
Якщо згенерувати slug неможливо, пакет викидає CouldNotGenerateSlugException. В контексті HTTP це автоматично повертає відповідь 422 з форматом помилки валідації. Ключ помилки за замовчуванням збігається з назвою колонки-джерела, але його можна змінити через errorKey. Оскільки виняток наслідує ValidationException, він не з'являтиметься в логах застосунку.
# Підтримка Unicode
Система транслітерує нелатинські символи у зрозумілі латинські slug та враховує контекст: наприклад, зберігає крапки у назвах хостів або шляхах до файлів замість того, щоб замінювати їх на дефіси.
Більше деталей про Laravel Sluggable можна знайти в репозиторії на GitHub.