Генератор slug
Превращает заголовок в slug для URL: транслитерация иврита, арабского, кириллицы и греческого, форма пути в Unicode и проверка совпадений.
creme-brulee-grusse-aus-munchencrème-brûlée-grüße-aus-münchencr%C3%A8me-br%C3%BBl%C3%A9e-gr%C3%BC%C3%9Fe-aus-m%C3%BCnchenБраузер показывает читаемую форму выше, а отправляет эту. Это один и тот же путь.
Что делает этот инструмент
Вставьте заголовок в любой письменности — и он вернётся тем slug, который выдержит URL: строчные буквы, никакой пунктуации, слова соединены выбранным вами разделителем. Латинские диакритики снимаются, а иврит, арабский, кириллица и греческий транслитерируются в латинские буквы.
Рядом со slug стоит тот же заголовок, сохранённый в собственной письменности. Эта форма — тоже законный путь, и для письменностей, которые теряют при транслитерации больше всего, она часто оказывается лучшим ответом. Поэтому обе строятся из одного заголовка, а не выбираются инструментом за вас.
Зачем нужен slug
Slug — это читаемая человеком часть URL: кусок после последней косой черты, который называет страницу, а не нумерует её. Он существует потому, что путь, читающийся как слова, переживает вставку в сообщение, печать на слайде и чтение вслух по телефону, а числовой идентификатор не переживает ничего из этого.
По той же причине его форма так стеснена. Slug должен быть устойчив — изменить его значит сломать каждую ссылку, уже указывающую на страницу, — и должен быть однозначен при записи от руки, что исключает пробелы, прописные буквы, которые читатель может воспроизвести, а может и нет, и пунктуацию, что-то значащую для оболочки или разборщика Markdown.
Как снимаются диакритики
Большинство латинских диакритик снимает платформа, а не таблица. Unicode определяет é как разложимую на простую e и следующее за ней комбинирующее акутовое ударение, поэтому нормализация к этой разложенной форме и последующее отбрасывание каждого комбинирующего знака оставляет простую букву. Та же операция справляется с ñ, ç, ő и ещё несколькими сотнями, и она не может устареть, поскольку опирается на данные Unicode, которые браузер уже несёт.
Она справляется не со всем, и об этом пробеле стоит знать. Буква, чей знак — черта, перечёркивающая глиф, а не значок над ним (ø, ł, đ, ħ, ŧ), — это единый неделимый символ вовсе без разложения, так что снятие знаков оставляет его ровно таким, каким он был. То же и с лигатурой: ß, æ и œ обозначают каждая последовательность звуков, а не букву с украшением. Всем им нужно явное написание, и без него они просто исчезли бы из slug.
Почему настройка языка меняет ответ
Единственно верной латинизации ü не существует. Немецкий пишет её ue ещё с тех пор, как умлаута не было, — две точки начались как маленькая надстрочная e, — поэтому Müller правильно будет mueller, и немецкому читателю muller покажется ошибкой. Французский, испанский и португальский обходятся со своими диакритиками как со значками над буквой, которая в остальном остаётся собой, поэтому crème brûlée правильно даёт creme-brulee, а написание cruemme было бы бессмыслицей.
Северные языки расходятся между собой ровно так же. Датский и норвежский удваивают гласную, следуя старому написанию, которое буква заменила; шведский — нет:
- Немецкий — ä становится ae, ö становится oe, ü становится ue, ß становится ss. München даёт muenchen.
- Датский и норвежский — æ становится ae, ø становится oe, å становится aa. Ålborg даёт aalborg.
- Шведский — ä становится a, ö становится o, å становится a. Ålborg даёт alborg.
- Общий — всякий знак отбрасывается, базовая буква сохраняется. Ålborg даёт alborg, München даёт munchen.
Это не соперничающие приближения к одному ответу; это четыре разных правильных ответа на четыре разных вопроса. По умолчанию может стоять лишь один, поэтому настройка на виду, и инструмент называет соглашение, которое дало то, что вы видите. Одна буква везде одинакова: ß — лигатура, а не диакритика, отбросить её значило бы стереть звук, и здесь она ss при любой настройке.
Письменности, которым нужна таблица
Ничто в браузере не латинизирует кириллицу, греческий, иврит и арабский, поэтому каждая из них — таблица, написанная вручную по опубликованному стандарту. Две выходят хорошо, потому что записывают свои гласные:
- Кириллица следует BGN/PCGN — латинизации англоязычных карт и паспортов: ж это zh, ч это ch, щ это shch, х это kh. Москва даёт moskva, а Чехов даёт chekhov.
- Греческий следует ELOT 743 вместе с диграфами, которые тот определяет: ου это ou, а не oy, и ευ это ev. Αθήνα даёт athina, а Ευρώπη даёт evropi.
ISO 9 — другой известный кириллический стандарт, и здесь он намеренно не используется. Он обратим, в этом весь его смысл, но добивается этого диакритиками: ж там ž. В slug нет места для гачека, так что буква тут же сплющилась бы в z — и Жуков с Зуковым дали бы один и тот же slug. Диграф BGN такое сплющивание переживает.
Одна деталь кириллической таблицы легко упускается и заслуживает быть названной. ё и й выглядят как буквы с диакритикой, и Unicode именно так их и раскладывает, но знак здесь — то, что делает их другими буквами, а не украшение на той же самой. Снять знаки до обращения к таблице — верный порядок для всякой другой письменности здесь — значит тихо превратить Ёлку в elka, а Андрея в andrei.
Иврит и арабский, и что они теряют
Обе письменности записывают согласные, а большинство гласных оставляют точкам, которых обычный текст не несёт. Это не проблема кодировки, которую инструмент решил бы таблицей получше: сведений просто нет в тексте. «מאמר» — четыре буквы, мем-алеф-мем-реш, и чтение maamar исходит от читателя, уже знающего слово. Побуквенно из него может выйти только mamr.
Что можно сделать — сделано. Там, где буква служит и знаком гласного, используется положение, потому что это единственный сигнал, который оставляет неогласованный текст:
- ו и י — согласные в начале слова и буквы-гласные внутри него, и именно это превращает שלום в shlom, а не в shlvm.
- Удвоенные וו или יי — согласный в обоих местах: этим удвоением иврит и различает два чтения.
- ב, כ и פ — взрывные в начале слова и щелевые внутри. Дагеш, отмечающий разницу, — это огласовка, так что остаётся только положение.
- Буква с последующим герешем — звук, для которого у алфавита нет буквы: ג׳ это j, צ׳ это ch, ז׳ это zh. Пренебречь им значило бы превратить ג׳אז в другое слово.
- Арабские эмфатические согласные сливаются со своими простыми парами, потому что в ASCII некуда поставить различающую их точку снизу. صابر и سابر дают один и тот же slug.
Результат читаем и узнаваем — и это не то написание, которое кто-нибудь назвал бы правильным. Инструмент говорит об этом при каждом ивритском или арабском результате, вместо того чтобы выдавать ответ с потерями за законченный, и указывает на форму ниже, которая не теряет ровно ничего.
Путь в Unicode, которому транслитерация не нужна
Путь URL не ограничен ASCII. RFC 3987 определяет IRI — идентификатор, который может содержать любой символ Unicode, — а правило передачи его по сети состоит в том, чтобы закодировать байты UTF-8 процентными последовательностями. Всякий браузер делает это два десятилетия, и потому Википедия отдаёт свои ивритские и русские заголовки статей под их собственными именами, а адресная строка показывает их читаемо.
Поэтому второй вывод здесь — заголовок с приведённой в порядок пунктуацией и пробелами и ничем больше не тронутый, а третий — то, как это выглядит в сети на самом деле. Это один и тот же путь: читаемая форма — то, что показывает браузер и что копирует человек, а закодированная — то, что записывает сервер.
Что выбрать — настоящее решение, а не формальность. Форма Unicode не теряет ничего, читается правильно для всякого, кто знает язык, и именно её покажет поисковая система. Транслитерированная форма переживает вставку туда, где кодировки портятся, помещается в системы, предполагающие пути в ASCII, и её можно прочесть по телефону. Для иврита и арабского в особенности форма Unicode обычно лучший ответ — как раз потому, что транслитерация не в силах вернуть гласные.
Совпадения, и почему они не разрешаются за вас
Построение slug снимает пунктуацию, поэтому заголовки, различающиеся только ею, перестают различаться вовсе. «Наше руководство по CSS» и «Наше руководство по CSS!» — это две записи и один slug. В режиме списка каждое такое столкновение отмечается строкой, с которой оно совпало, потому что это и есть та неполадка, которую система управления содержимым прячет: она молча добавляет суффикс, публикует, и ожидаемый вами адрес принадлежит другой записи.
Суффикс доступен как переключатель и даёт стиль WordPress и Django — nashe-rukovodstvo-po-css, nashe-rukovodstvo-po-css-2 — на случай, когда список нужно вставить куда-то как есть. По умолчанию он выключен, потому что совпадение обычно проблема содержания, а не именования, и совпадение остаётся отмеченным даже при включённом переключателе: включить его — не значит что-либо спрятать.
Длина, и обрезка в нужном месте
Ограничение длины режет по границе разделителя и никогда внутри слова. Обрезка посреди слова даёт не столько более короткий slug, сколько другой — introduction-to-crypt это не более опрятный introduction-to-cryptography, — а половина слова есть слово, значащее иное. Если единственное слово длиннее предела, границы для реза нет, и оно возвращается целиком, а не рассечённым.
Универсально верного предела не существует. Поисковые системы показывают примерно первые шестьдесят-семьдесят символов адреса, а старые системы иногда ограничивают сегмент пути, но ни на каком конкретном числе ничего не ломается. Оставленное пустым поле оставляет slug таким длинным, какого требует заголовок.
Частые вопросы
- Какие символы безопасны в slug для URL?
- Строчные буквы ASCII, цифры и один разделитель сработают везде без исключений. Дефис — привычный разделитель; подчёркивание работает так же, но хуже видно под подчёркнутой ссылкой. Пробелы, прописные буквы и пунктуация технически кодируются и все на практике доставляют хлопоты, поэтому slug их убирает.
- Дефис или подчёркивание?
- Дефис, по двум причинам, переживающим моду. Его использует всякая крупная платформа, а значит, его ждут и читатели, и другие инструменты, и он исчезает под подчёркиванием, которое несёт большинство ссылок, — чего о подчёркивании не скажешь. Выбор предлагается здесь потому, что у существующих систем есть существующие соглашения, и единообразие внутри одного сайта важнее любого из двух ответов.
- Почему заголовок на иврите или арабском теряет гласные?
- Потому что их и не писали. Обе письменности отмечают большинство гласных точками, которые обычный текст опускает, поэтому побуквенное чтение — всё, что любой инструмент может выдать без огласовочного движка, угадывающего задуманное слово. Этот транслитерирует то, что действительно есть, сообщает об этом рядом с результатом и предлагает форму пути в Unicode, сохраняющую заголовок ровно таким, каким его набрали.
- Может ли URL содержать иврит, арабский или китайский напрямую?
- Да. Путь может нести любой символ Unicode; в сети он кодируется процентами как UTF-8, а браузер показывает его читаемо. Именно так Википедия отдаёт названия статей на всех языках, которые охватывает. Этот инструмент показывает и читаемую форму, и закодированную, поскольку вторая — то, что появляется в журналах сервера и в аналитике.
- Почему Müller то mueller, то muller?
- Потому что верно и то и другое, в разных языках. Немецкий выписывает умлаут полностью — две точки родились как маленькая надстрочная e, — тогда как французский и испанский обходятся со своими диакритиками как со значками над буквой, которая в остальном остаётся собой. Настройка языка выбирает соглашение, и инструмент сообщает, какое именно он применил.
- Почему два моих заголовка дают один и тот же slug?
- Потому что построение slug убирает пунктуацию и регистр, а это часто единственное, что разделяет два заголовка. Режим списка отмечает каждое совпадение строкой, с которой оно столкнулось. Можно включить суффикс -2 в духе WordPress, но лежащий глубже вопрос — должны ли две записи действительно носить почти одно имя — стоит решить первым.
- Отправляется ли что-нибудь из набранного на сервер?
- Нет. Все преобразования выполняются в вашем браузере; ничто не загружается и не записывается, и всё работает без сетевого соединения.