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

Viacjazyčné slugy

Slugový stĺpec sa stane jazykovou mapou (locale map) — jeden slug na jazyk v jedinom json/jsonb stĺpci — ak model preň implementuje ProvidesLocaleMaps, ak má stĺpec cast array/json/object/collection, alebo ak zavoláte ->localized(). Najprv uveďte jazyky, v ktorých váš web beží (predvolene app.locale + app.fallback_locale):

// config/sluggable.php — the locales your site serves (default: app.locale + app.fallback_locale)
'locales' => ['supported' => ['en', 'sk', 'de']],
final class Topic extends Model implements Sluggable
{
    use HasSlug;

    protected $fillable = ['name', 'slug'];

    protected $casts = ['name' => 'array', 'slug' => 'array'];
}

$topic = Topic::create(['name' => ['en' => 'Investing', 'sk' => 'Investovanie', 'de' => 'Straße']]);
$topic->slug;   // ['en' => 'investing', 'sk' => 'investovanie', 'de' => 'strasse']
  • Každý jazyk sa transliteruje podľa vlastných pravidiel (de: ß → ss).
  • Zdroje s jazykovou mapou sa čítajú priamo, nikdy nie cez getAttribute() — prekladové traity tam vracajú reťazec aktuálneho jazyka — takže slovenský slug vznikne vždy zo slovenského názvu.
  • Slugy sa generujú len v jazykoch, v ktorých ich vyhľadávanie dokáže nájsť — aktuálny a záložný jazyk, SlugLocales::supported() a explicitný zoznam locales([...]) — takže každý slug aj každý route kľúč sa vyhodnotí.
  • Prázdne hodnoty a JSON null sa ignorujú; jazyky, ktoré sluggable negeneruje, zostanú zachované.
  • Model s metódou isLocaleMapAttribute() (napr. cez HasTranslations), ktorý neimplementuje ProvidesLocaleMaps, sa odmietne (localeMapContractMissing) — nepovažuje sa potichu za reťazcový stĺpec.

Čítanie jazykovej mapy

$topic->currentSlug();      // current locale, then the chain (fallback, then every resolvable locale)
$topic->slugFor('sk');      // exact locale, no fallback
$topic->slugMap();          // ['en' => …, 'sk' => …]  (string column: ['*' => …])

Výber jazykov a záložných jazykov

use RoundlyConsulting\Sluggable\Enums\LocaleFallback;
use RoundlyConsulting\Sluggable\Enums\TargetLocales;

SlugDefinition::for('slug')->from('name')
    ->localized()                                 // force locale-map storage
    ->locales(TargetLocales::Supported)           // or ['en', 'sk'] / fn (Model $m): list<string>
    ->fallback(LocaleFallback::Fallback)
    ->fallbackLocale('en')
    ->uniqueAcrossLocales();                      // application-level only
locales()Generuje
TargetLocales::SourcePredvolené. Jazyky zdrojov spomedzi vyhľadateľných; zdroj zapísaný len v iných jazykoch aj tak dostane slug, v aktuálnom jazyku.
TargetLocales::SupportedKaždý jazyk z SlugLocales::supported() (chýbajúce zdroje prejdú na záložný jazyk).
TargetLocales::CurrentLen jazyk aktuálnej požiadavky.
['en', 'sk']Zadané jazyky — vyhľadávanie ich prehľadáva rovnako ako podporované.
fn (Model $m): list<string>Jazyky z closure, obmedzené na vyhľadateľnú množinu.

fallback() určuje reťazec pre čítanie a binding: LocaleFallback::None (len aktuálny jazyk), Fallback (aktuálny, potom záložný jazyk) alebo Any (predvolené — potom každý vyhľadateľný jazyk, takže URL v ktoromkoľvek z nich sa aj tak vyhodnotí). fallbackLocale() prepíše samotný záložný jazyk.

Reťazcový slug vytváraný zo zdroja s jazykovou mapou použije sourceLocale(); bez neho záložný jazyk, potom aktuálny jazyk a nakoniec prvú hodnotu podľa kľúča:

SlugDefinition::for('slug')->from('name')->sourceLocale('en');   // string slug from the en name

Jedinečnosť podľa jazyka

perLocaleUniqueness() (predvolené) overuje každý jazyk samostatne, takže red-chair môže existovať raz v každom jazyku. uniqueAcrossLocales() vyžaduje jedinečnosť naprieč všetkými jazykmi — vynucuje ju len aplikácia, pretože žiadny index to nedokáže vyjadriť.

Odkiaľ sa berú jazyky

Podporované, záložný a aktuálny jazyk poskytuje kontrakt SlugLocales. Sluggable naviaže predvolenú implementáciu z konfigurácie (sluggable.locales.*, inak app.locale a app.fallback_locale) cez bindIf(); translatable-for-laravel ju previaže na vlastný zdroj jazykov; vaše vlastné naviazanie má prednosť pred oboma:

use RoundlyConsulting\Sluggable\Contracts\SlugLocales;

final class AppSlugLocales implements SlugLocales
{
    public function supported(): array
    {
        return ['en', 'sk', 'de'];
    }

    public function fallback(): ?string
    {
        return 'en';
    }

    public function current(): string
    {
        return app()->getLocale();
    }
}

// AppServiceProvider::register()
$this->app->singleton(SlugLocales::class, AppSlugLocales::class);

Kontrakt ProvidesLocaleMaps

ProvidesLocaleMaps implementujte, ak mapu spravuje prekladová vrstva — sluggable potom číta a zapisuje cez ňu namiesto priameho atribútu:

namespace RoundlyConsulting\Sluggable\Contracts;

interface ProvidesLocaleMaps
{
    public function isLocaleMapAttribute(string $key): bool;

    /** @return array<string, string> blank values already dropped */
    public function getLocaleMap(string $key): array;

    /** @param array<string, string> $map */
    public function setLocaleMap(string $key, array $map): static;
}

Pre samotný stĺpec zvolí makro localizedSlug() správny typ podľa databázy:

$table->localizedSlug('slug');   // jsonb (pgsql) / json (mysql) / text (sqlite)

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.