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

Názvy, slugy a preklady

Reťazec označuje štítok, ktorého slug sa v niektorom jazyku reťaze zhoduje so slugom reťazca v tomto jazyku — vypočítaným vlastným postupom sluggable-for-laravel. Pravopis, veľkosť písmen ani interpunkcia preto nikdy nevytvoria druhý štítok:

$rock = Tags::type('label')->findOrCreate('Rock');

Tags::type('label')->findOrCreate('ROCK!')->is($rock);   // true — one tag per slug
Tags::type('label')->findOrCreate('  rock.  ')->is($rock); // true
Tags::type('label')->find('rock')->is($rock);            // true — a slug names its tag

// The dictionary keeps these three tags apart: c, c-plus-plus, c-sharp
Tags::type('label')->findOrCreate('C');
Tags::type('label')->findOrCreate('C++');
Tags::type('label')->findOrCreate('C#');
  • Názov sa oreže, odstránia sa z neho riadiace a neviditeľné znaky a medzery sa zlúčia do jednej. Prázdny názov alebo názov dlhší než tags.names.max_length vyhodí InvalidTagException; rovnako názov, z ktorého sa nedá zostaviť slug.
  • Reťaz jazykov tvorí aktuálny jazyk, potom záložný jazyk a potom všetky ostatné podporované. Každý jazyk vytvára slug s vlastnou transliteráciou — Über je v nemčine ueber, v angličtine uber.
  • Rovnaký slug v dvoch jazykoch môže patriť dvom štítkom (gift je v angličtine darček a v nemčine jed): vyhrá jazyk, ktorý je v reťazi skôr.
  • Slugy sú unikátne pre typ, rozsah a jazyk, vrátane zmazaných štítkov, a nikdy sa k nim nepridáva prípona: obsadený slug je ten istý štítok alebo duplicita — nikdy rock-2.

Každý jazyk

Obyčajný reťazec je aktuálny jazyk; mapa jazykov nastaví viacero naraz. Chybné kľúče jazykov vyhodia výnimku a kľúče mimo translatable.locales sa zahodia — balík nemôže poznať jazyky aplikácie. Aktuálny jazyk musí byť podporovaný, inak obyčajný reťazec štítok označiť nemôže:

// A plain string is the current locale; a map sets several at once
$music = Tags::type('genre')->make(['en' => 'Music', 'sk' => 'Hudba'])->create();

$music->name;                        // 'Music' in en, 'Hudba' in sk
$music->slugFor('sk');               // 'hudba'
$music->getTranslations('name');     // ['en' => 'Music', 'sk' => 'Hudba']

app()->setLocale('sk');
Tags::type('genre')->find('music')->is($music);   // true — the chain falls back to en
Tags::type('genre')->find('Hudba')->is($music);   // true

// A rename changes only the locales it names; each slug follows its own name
Tags::type('genre')->rename($music, ['sk' => 'Hudobné žánre']);

Duplicity a rezervované názvy

use RoundlyConsulting\Tags\DataTransferObjects\TagData;

$pop = Tags::type('label')->make('Pop')->create();
Tags::type('label')->make('POP')->create();
// DuplicateTagException: A tag with the slug [pop] in [en] already exists.

$rock = Tags::type('label')->make('Rock')->color('#000000')->create();
Tags::type('label')->delete($rock);

// A deleted tag keeps its name: creating it again restores that tag, with the new attributes
$again = Tags::type('label')->create(new TagData(name: 'Rock', color: '#ffffff'));
$again->is($rock);                    // true — TagRestored fires, and it carries no old taggings

// Renaming another tag onto a deleted tag's slug is refused
Tags::type('label')->rename($pop, 'Rock');
// DuplicateTagException: A deleted tag holds the slug [rock] in [en]: restore that tag instead.

Zmazaný štítok si svoj názov ponechá. Opätovné použitie názvu tento štítok obnoví namiesto toho, aby vznikol nový — vždy bez starých priradení, takže staré záznamy sa nikdy neoznačia nanovo. V akej podobe sa vráti, závisí od volania:

use RoundlyConsulting\Tags\DataTransferObjects\TagData;

$genres = Tags::type('genre');
$genres->delete($jazz);       // Jazz sat under Music, with a colour, an icon and a description

// Any one of these brings the deleted Jazz back, without its old taggings:
$genres->findOrCreate('jazz');                                 // as it was — names, colour, icon, description, under Music
$genres->make('Jazz')->color('#ffffff')->findOrCreate();       // still as it was: of the builder's data only a parent applies
$genres->make('Jazz')->under($rock)->findOrCreate();           // as it was, moved under Rock
$genres->create(new TagData(name: 'Jazz', color: '#ffffff'));  // with exactly these attributes (no icon, no description), under Music
$genres->make('Jazz')->under(null)->create();                  // with these attributes, as a root

// With Music deleted too, create() and findOrCreate() refuse (InvalidTagHierarchyException,
// "restore it first") unless a parent is given; a free-form name comes back as a root instead
$article->attachTags('Physics', 'topic');                      // 'topic' is hierarchical()->freeForm()
  • findOrCreate() — s názvom, mapou jazykov, builderom alebo TagData — a voľný názov v attachTags() či syncTags() ho vrátia taký, aký bol: so všetkými názvami, popisom, slugmi, farbou a ikonou, na aktuálnom mieste jeho rodiča. Z údajov buildera sa uplatní len rodič zadaný cez under().
  • create() použije vlastné atribúty — názvy, popis, ručné slugy, farbu a ikonu, takže čo vynechá, sa vymaže — a štítok nechá tam, kde bol, pokiaľ nezadáte rodiča (under(null) alebo parent: null žiada koreň); uplatní sa aj zadaná pozícia.
  • Ak je zmazaný aj jeho rodič, create() a findOrCreate() bez zadaného rodiča odmietnu s InvalidTagHierarchyException („restore it first“), kým voľný názov ho vráti ako koreň, rovnako ako každý voľný štítok stromu.
  • V každom prípade platí limit hĺbky typu, cesty jeho zmazaných potomkov ho nasledujú a nikdy sa nedostane pod vlastné dieťa (obyčajné $tag->delete() môže nechať živé deti). Vytvorenie, ktorého jazyky držia dva rôzne zmazané štítky, sa odmietne.

Stabilné a ručné slugy

Bez stableSlugs() sa slug jazyka pri každom premenovaní riadi jeho názvom — starý slug štítok prestane označovať. So stableSlugs() (len kurátorované typy) sa slugy nikdy negenerujú nanovo, takže URL kategórie sa nepohne — slug dostane len jazyk pomenovaný prvýkrát, a to raz; slug nového názvu štítok označí až vtedy, keď to určí ručný slug. Premenovanie na slug zmazaného štítku odkáže na restore() aj pri type so stabilnými slugmi:

use RoundlyConsulting\Tags\DataTransferObjects\UpdateTagData;

Tags::define('genre')->hierarchical()->stableSlugs();
$jazz = Tags::type('genre')->make('Jazz')->create();

$renamed = Tags::type('genre')->rename($jazz, 'Jazz music');
$renamed->name;                                     // 'Jazz music'
$renamed->slug;                                     // 'jazz' — /events?category=jazz still works

// Curated types also take a manual slug, already in slug form
$blues = Tags::type('genre')->make('Blues and soul')->slug('blues')->create();
Tags::type('genre')->update($blues, new UpdateTagData(slug: 'blues-soul'));

Ručný slug je len pre kurátorované typy (na voľnom type InvalidTagException) a musí už mať tvar slugu — malé písmená, číslice a oddeľovače, najviac tags.slugs.max_length znakov. Slug, ktorý drží iný štítok, je DuplicateTagException.

Popisy, farby a ikony

$music = Tags::type('genre')
    ->make(['en' => 'Music', 'sk' => 'Hudba'])
    ->description(['en' => 'Concerts and festivals.', 'sk' => 'Koncerty a festivaly.'])
    ->color('#F24E29')          // a hex colour, stored lower-case: #f24e29
    ->icon('music')             // an identifier (music, fa-guitar) or an emoji, at most 64 characters
    ->create();

Tags::type('genre')->edit($music)->color(null)->icon(null)->save();   // null clears
  • Popis je čistý text — bez značiek a bez riadiacich znakov okrem zalomení riadkov a tabulátorov — s najviac tags.descriptions.max_length znakmi na jazyk. Prázdne jazyky sa zahodia.
  • Farba je hexadecimálna hodnota #rrggbb, uložená malými písmenami.
  • Ikona je identifikátor (music, fa-guitar) alebo emoji: najviac 64 znakov, bez medzier, riadiacich znakov, úvodzoviek a lomených zátvoriek.
  • Typ a vlastník štítku sa nikdy nemenia: ich zmena vyhodí InvalidTagException. Presun štítku medzi rozsahmi nie je podporovaný.

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.