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::Source | Predvolené. Jazyky zdrojov spomedzi vyhľadateľných; zdroj zapísaný len v iných jazykoch aj tak dostane slug, v aktuálnom jazyku. |
TargetLocales::Supported | Každý jazyk z SlugLocales::supported() (chýbajúce zdroje prejdú na záložný jazyk). |
TargetLocales::Current | Len 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 nameJedineč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 kryptomienOdoslaní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.