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

Smerovanie a bezpečnosť URL

Pri zapnutom posts.slugs.route-binding (predvolene) je slug route kľúčom príspevku. {post} aj {post:slug} sa viažu podľa slugu v aktuálnom jazyku, potom v záložnom, potom v ľubovoľnom, a route() generuje slug v aktuálnom jazyku — URL a väzba sú tak vždy v súlade. Číselný slug nikdy nezatieni id príspevku:

use RoundlyConsulting\Posts\Models\Post;

Route::get('/posts/{post}', fn (Post $post) => view('posts.show', compact('post')))->name('posts.show');

route('posts.show', $post);   // /posts/hello-world — the current locale's slug

Ak route-binding vypnete, zostane predvolená väzba Laravelu podľa kľúča.

História slugov a 301 presmerovania

Zapnite posts.slugs.history a balík si bude pamätať vyradené slugy príspevkov: požiadavka na starý slug dostane 301 na aktuálnu URL, vrátane query stringu. Vyžaduje to tabuľku histórie zo sluggable:

# .env
POSTS_SLUG_HISTORY=true

php artisan vendor:publish --tag="sluggable-migrations"
php artisan migrate

Pri uuid alebo ulid príspevkoch nastavte pred migráciou tabuľky histórie sluggable.key_type na rovnakú hodnotu ako posts.primary_key_type.

Zámok publikovaných URL

Zapnite posts.slugs.lock-when-published a slugy príspevku sa po publikovaní zmrazia: nič ich nepregeneruje a ručná zmena vyhodí SlugLockedException. Zámernú zmenu obaľte do Slugs::unlocked():

// config/posts.php
'slugs' => [
    // …
    'lock-when-published' => true,
],

Posts::publish($post);
$post->setTranslation('slug', 'en', 'new-url')->save();   // throws SlugLockedException

use RoundlyConsulting\Sluggable\Facades\Slugs;

Slugs::unlocked(fn () => $post->setTranslation('slug', 'en', 'new-url')->save());

Validácia zadaných slugov

Post::slugRules() vráti pravidlá pre formulár, ktorý prijíma mapu slugov (slug.en, slug.sk, …), s rovnakou kontrolou unikátnosti ako pri generovaní. Upravovaný príspevok odovzdajte, aby sa ignoroval:

$request->validate([...Post::slugRules($post), 'title' => ['required', 'array']]);

// Post::slugRules() returns a 'slug' rule set: nullable, array, and sluggable's
// UniqueSlug on the configured posts.model, ignoring $post

Ak majú administrátori namiesto tichého -2 vidieť validačnú chybu, skombinujte tieto pravidlá s manuálnou politikou Strict zo sluggable vo vlastnej podtriede modelu. Strict uloží ručný slug presne tak, ako bol zadaný, a obsadený odmietne výnimkou SlugAlreadyTakenException, preto pridajte aj pravidlo ValidSlug zo sluggable, ktoré odmietne vstup, ktorý ešte nie je slugom:

use RoundlyConsulting\Posts\Models\Post;
use RoundlyConsulting\Sluggable\Definitions\SlugOptions;
use RoundlyConsulting\Sluggable\Enums\ManualSlugPolicy;
use RoundlyConsulting\Sluggable\Rules\ValidSlug;

// Configure it as posts.model
class Article extends Post
{
    public function slugOptions(): SlugOptions
    {
        $options = parent::slugOptions();
        $options->get('slug')->manual(ManualSlugPolicy::Strict);

        return $options;
    }
}

// Strict stores a manual slug as typed, so check its format in the form too
$rules = Article::slugRules($article);
$rules['slug'][] = ValidSlug::for(Article::class);

$request->validate([...$rules, 'title' => ['required', 'array']]);
// slug.en = 'taken'       → "The slug.en (en) has already been taken."
// slug.en = 'Custom Slug' → "The slug must be a valid slug (…)."

// A save that skips the form throws instead of saving taken-2:
$article->setTranslation('slug', 'en', 'taken')->save();   // SlugAlreadyTakenException

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.