NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Sluggable for Laravel

Formátovanie a sufixy

Každý slug prechádza jednou čistou pipeline — bez databázy. V tomto poradí:

  • Ohraničenie — odstráni neplatné UTF-8 a skráti zdroj na limits.max_source_length ešte pred spustením akéhokoľvek regexu.
  • Čistenie — odstráni riadiace znaky a znaky nulovej šírky či smeru textu; v režime unicode vykoná NFKC normalizáciu, ak je načítané ext-intl.
  • Transliterácia — Str::ascii() v jazyku definície (jazykové mapy v jazyku každej položky); v režime unicode sa vynechá.
  • Otočenie oddeľovača — druhý z dvojice - a _ sa zmení na oddeľovač.
  • Slovník — náhrady ako @ → at, obklopené oddeľovačom.
  • Malé písmená — ešte pred odstránením znakov, presne v poradí Str::slug().
  • Odstránenie a zlúčenie — ponechá písmená, číslice a oddeľovač; zlúči opakovania a oreže okraje.
  • Slová a dĺžka — ponechá prvých maxWords slov a potom skráti na maxLength.

S predvoleným formátom (ASCII, malé písmená, -, ['@' => 'at']) sa výstup pri bežnom vstupe do 255 znakov zhoduje so Str::slug(). Dva rozdiely sú zámerné:

  • Znaky nulovej šírky a riadiace znaky bidi sa odstránia ešte pred transliteráciou — zero\u{200B}width dá zerowidth, kým Str::slug() vráti zero-width.
  • Slug je obmedzený na max_length (255) a vzniká z prvých max_source_length (2000) znakov zdroja; Str::slug() žiadny limit nemá.

Fasáda sprístupňuje pipeline priamo:

use RoundlyConsulting\Sluggable\Facades\Slugs;

Slugs::slugify('Žltý kôň @ home', language: 'sk');     // 'zlty-kon-at-home'

Tvarovanie slugu

SlugDefinition::for('slug')
    ->from('title')
    ->language('de')                                  // or fn (?string $locale): ?string
    ->dictionary(['&' => 'and', '@' => 'at'])
    ->maxWords(8)
    ->prefix(fn (Post $post, ?string $locale): ?string => $post->published_at?->format('Y'))
    ->reserved(['admin', 'login']);
  • separator() — 1–3 znaky z - . _ ~.
  • maxLength() — 8–2048 znakov vrátane predpony, prípony a kolízneho sufixu; maxWords() obmedzí počet slov.
  • language() — kód jazyka alebo fn (?string $locale): ?string; dictionary() — náhrady aplikované pred odstránením znakov.
  • unicode() zachová ne-ASCII písmená namiesto transliterácie; lowercase(false) zachová veľké písmená.
  • prefix() / suffix() — pevné reťazce alebo closures; prechádzajú rovnakou pipeline a skracovanie ich nikdy neoreže.
  • reserved() — ďalšie slová, ktoré sa počítajú ako obsadené, navyše ku globálnej konfigurácii reserved (bez ohľadu na veľkosť písmen).

Skracovanie je bezpečné pre viacbajtové znaky: reže pri poslednom oddeľovači, ak leží v druhej polovici limitu, inak reže natvrdo a potom oreže oddeľovače na okrajoch.

Vlastný slugger

using() nahradí kroky formátovania vlastnou closure. Jej výstup sa aj tak overí ako bezpečný segment URL — len písmená, číslice, diakritické značky a oddeľovač — inak sa vyhodí SlugGenerationException (invalidCustomOutput):

use Illuminate\Support\Str;

SlugDefinition::for('slug')->from('name')->using(
    fn (string $source, ?string $locale): string => Str::of($source)->lower()->replace(' ', '-')->toString(),
);

Kolízne sufixy

Ak je základný slug obsadený, pripojí sa sufix. Stratégiu zvolíte pre každú definíciu:

use RoundlyConsulting\Sluggable\Definitions\ResolvedSlugDefinition;

SlugDefinition::for('slug')->from('name');                              // chair, chair-2, chair-3 …
SlugDefinition::for('slug')->from('name')->sequentialSuffix(start: 1);  // chair, chair-1, chair-2 …
SlugDefinition::for('slug')->from('name')->randomSuffix(6);             // chair, then chair- + 6 random [a-z0-9]
SlugDefinition::for('slug')->from('name')->suffixUsing(
    fn (string $base, int $attempt, ResolvedSlugDefinition $definition): string => 'v'.$attempt,
);

Sekvenčné sufixy (predvolené, od 2) overia v dávkach až limits.sequential_probes kandidátov a potom prejdú na náhodné. randomSuffix() generuje sufixy [a-z0-9] s dĺžkou randomLength znakov (4–32). Pre čokoľvek iné implementujte kontrakt SuffixGenerator — dostane základ, poradové číslo pokusu (od 1) a vyhodnotenú definíciu a vráti sufix bez oddeľovača:

use RoundlyConsulting\Sluggable\Contracts\SuffixGenerator;
use RoundlyConsulting\Sluggable\Definitions\ResolvedSlugDefinition;

final class YearSuffix implements SuffixGenerator
{
    public function suffix(string $base, int $attempt, ResolvedSlugDefinition $definition): string
    {
        return now()->year.'-'.$attempt;
    }
}

SlugDefinition::for('slug')->from('name')->suffixUsing(new YearSuffix);

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.