Slug із транслітерацією
Перетворити українську назву на URL-адресу
Дані надсилаються на сервер, але не зберігаються
Цей інструмент не можна виконати у браузері, тому введені дані надсилаються на наш сервер. Ми обробляємо їх у пам'яті та одразу повертаємо результат: нічого не записується в базу, у файли чи в логи, нічого не передається третім сторонам. Та все ж не вставляйте сюди справжні робочі паролі чи ключі - для чутливих даних краще скористатися локальними інструментами.
Дві транслітерації, і вони різні
Для української назви існує два розумні способи зробити URL, і вони дають різний результат.
Str::slug() - те, що зробить Laravel, якщо ви напишете Str::slug($post->title). Саме цей рядок опиниться в адресі статті чи вакансії.
КМУ 55 - офіційна транслітерація, затверджена постановою Кабміну 2010 року. Це те, як ваше ім'я пишуть у закордонному паспорті й як українські топоніми подають у документах.
Різниця не косметична:
| Оригінал | Str::slug | КМУ 55 |
|---|---|---|
| Їжак | yizak | yizhak |
| щука | shhuka | shchuka |
| Київ | kijev | kyiv |
| Юрій | iurii | yurii |
Str::slug губить ж у «Їжак» і перетворює щ на shh замість shch. Для URL це переживається - адреса лишається унікальною й читабельною. Для документа, візитки чи назви компанії латиницею - ні.
Чому Str::slug працює саме так
Str::slug() не знає української. Він проганяє рядок через загальну таблицю транслітерації Unicode, побудовану переважно для західноєвропейських мов, і бере найближчі відповідники. Тому «Київ» стає kijev - через російсько-німецьку традицію, а не українську.
Це не помилка Laravel: універсальна таблиця не може знати, що саме ця кирилиця - українська, а не болгарська чи сербська.
Що з цим робити на практиці
Для URL лишайте Str::slug(). Він передбачуваний, уже використовується в наявних посиланнях, і міняти його заднім числом означає зламати всі старі адреси.
Якщо потрібна правильна транслітерація - для експорту, документів, латинської назви компанії - беріть КМУ 55 і зберігайте окремим полем.
// Slug генерується один раз при створенні і далі не змінюється:
// зміна заголовка не має ламати посилання, які вже десь опубліковані.
protected static function booted(): void
{
static::creating(function (self $post): void {
$post->slug ??= Str::slug($post->title);
});
}
Унікальність
Str::slug() нічого не знає про те, що така адреса вже зайнята. Дві вакансії «Middle Laravel Developer» дадуть однаковий slug і другий запис впаде на унікальному індексі.
$slug = Str::slug($title);
$base = $slug;
$i = 2;
while (Vacancy::where('slug', $slug)->exists()) {
$slug = $base . '-' . $i++;
}
Альтернатива - додати до slug короткий ідентифікатор: middle-laravel-developer-a7f3. Довше, але без запиту в циклі.
Довжина і SEO
Занадто довгий slug ріжеться у видачі й погано читається в месенджері. Розумна межа - близько 60-70 символів:
$slug = Str::slug(Str::limit($title, 60, ''));
Обрізати треба заголовок до транслітерації, а не slug після: інакше можна відрізати посеред shch і отримати обірваний хвіст.
Якщо потрібне не посилання, а перетворення між camelCase і snake_case - це зміна регістру.
- Де виконується
- на сервері
- Категорія
- Текст