PHP code example of oliwol / laravel-slugify

1. Go to this page and download the library: Download oliwol/laravel-slugify library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

oliwol / laravel-slugify example snippets


use Oliwol\Slugify\HasSlug;
use Oliwol\Slugify\Slugify;

#[Slugify(from: 'title', to: 'slug')]
class Post extends Model
{
    use HasSlug;
}

use Oliwol\Slugify\HasSlug;

class Post extends Model
{
    use HasSlug;

    public function getAttributeToCreateSlugFrom(): string|array
    {
        return 'title';
    }

    public function getRouteKeyName(): string
    {
        return 'slug';
    }
}

use Oliwol\Slugify\Slugify;

#[Slugify(from: 'title', to: 'slug')]
class Post extends Model
{
    // No trait 

// config/slugify.php
'models' => [
    App\Models\Post::class,
],

use Oliwol\Slugify\HasSlug;
use Oliwol\Slugify\Slugify;

// Full configuration via attribute
#[Slugify(from: 'name', to: 'slug')]
class Post extends Model
{
    use HasSlug;
}

// Only 'from' — slug column is determined by getRouteKeyName()
#[Slugify(from: 'name')]
class Post extends Model
{
    use HasSlug;

    public function getRouteKeyName(): string
    {
        return 'slug';
    }
}

// Multiple source attributes — generates slug from combined values
#[Slugify(from: ['first_name', 'last_name'], to: 'slug')]
class Author extends Model
{
    use HasSlug;
}
// first_name: "John", last_name: "Doe" → "john-doe"

// Custom separator — uses underscores instead of hyphens
#[Slugify(from: 'title', to: 'slug', separator: '_')]
class Post extends Model
{
    use HasSlug;
}
// "Hello World" → "hello_world"

// Method source — use a model method for complex slug generation
#[Slugify(from: 'getFullTitle', to: 'slug')]
class Post extends Model
{
    use HasSlug;

    public function getFullTitle(): string
    {
        return $this->category->name . ' ' . $this->title;
    }
}
// category: "Tech", title: "Laravel Tips" → "tech-laravel-tips"
// Note: dirty detection is skipped — the slug is always regenerated on save.

// SEO-safe — slug is only generated on creation, never updated
#[Slugify(from: 'title', to: 'slug', regenerateOnUpdate: false)]
class Post extends Model
{
    use HasSlug;
}

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Oliwol\Slugify\HasSlug;

class Post extends Model
{
    use HasSlug;

    /**
     * Attribute(s) used for generating the slug.
     * Return a string or an array of strings.
     */
    public function getAttributeToCreateSlugFrom(): string|array
    {
        return 'name';
    }

    /**
     * Use slug for route binding.
     */
    public function getRouteKeyName(): string
    {
        return 'slug';
    }

    /**
     * This package uses Laravel's getRouteKeyName to store the slug.
     * If you are using a different column for your routes,
     * use getAttributeToSaveSlugTo to store the slug.
     */
    public function getAttributeToSaveSlugTo(): string
    {
        return 'slug';
    }

    /**
     * Scope applied when checking for uniqueness.
     */
    public function scopeSlugQuery($query)
    {
        return $query->where('tenant_id', 1);
    }
}

$table->string('slug')->unique();

$table->unique(['tenant_id', 'slug']);

protected static function bootHasSlug(): void
 {
     static::saving(function (Model $model): void {
         if ($model->isSluggable()) {
             $model->createSlug();
         }
     });
 }

// Returns the model or null
$post = Post::findBySlug('hello-world');

// Returns the model or throws ModelNotFoundException
$post = Post::findBySlugOrFail('hello-world');

use Oliwol\Slugify\HasSlug;
use Oliwol\Slugify\HasSlugHistory;
use Oliwol\Slugify\Slugify;

#[Slugify(from: 'title', to: 'slug')]
class Post extends Model
{
    use HasSlug, HasSlugHistory;
}

$post = Post::create(['title' => 'Laravel Tips']);
// slug: "laravel-tips"

$post->update(['title' => 'Advanced Laravel Tips']);
// slug: "advanced-laravel-tips"
// history: ["laravel-tips"]

// Find by current slug
Post::findBySlugWithHistory('advanced-laravel-tips'); // → Post

// Find by old slug (useful for 301 redirects)
Post::findBySlugWithHistory('laravel-tips'); // → Post

// Returns null if neither current nor historical slug matches
Post::findBySlugWithHistory('nonexistent'); // → null

Route::get('/posts/{post:slug}', PostController::class)
    ->middleware(['slug.redirect']);

public function show(string $slug)
{
    $post = Post::findBySlugWithHistory($slug);

    if (! $post) {
        abort(404);
    }

    // If the slug doesn't match the current one, redirect
    if ($post->slug !== $slug) {
        return redirect()->route('posts.show', $post->slug, 301);
    }

    return view('posts.show', compact('post'));
}

$post->slugHistory; // Collection of SlugHistory entries

$post->slugHistory->pluck('slug'); // ["old-slug", "older-slug"]

// Each entry is timestamped
$post->slugHistory->first()->created_at; // Carbon instance

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->json('title')->nullable();
    $table->json('slug')->nullable();
});

use Oliwol\Slugify\HasTranslatableSlug;
use Oliwol\Slugify\Slugify;
use Spatie\Translatable\HasTranslations;

#[Slugify(from: 'title', to: 'slug')]
class Post extends Model
{
    use HasTranslations, HasTranslatableSlug;

    public array $translatable = ['title', 'slug'];
}

$post = Post::create([
    'title' => ['en' => 'Hello World', 'de' => 'Hallo Welt'],
]);

$post->getTranslation('slug', 'en'); // → 'hello-world'
$post->getTranslation('slug', 'de'); // → 'hallo-welt'

Post::create(['title' => ['en' => 'Hello', 'de' => 'Erster']]);
$second = Post::create(['title' => ['en' => 'Hello', 'de' => 'Zweiter']]);

$second->getTranslation('slug', 'en'); // → 'hello-2'  (incremented)
$second->getTranslation('slug', 'de'); // → 'zweiter'  (untouched)

Post::findBySlug('hello-world', 'en'); // → Post
Post::findBySlug('hallo-welt', 'de');  // → same Post

// Without explicit locale, uses the current app locale:
app()->setLocale('de');
Post::findBySlug('hallo-welt'); // → Post

#[Slugify(from: 'getFullTitle', to: 'slug')]
class Post extends Model
{
    use HasTranslations, HasTranslatableSlug;

    public array $translatable = ['title', 'slug'];

    public function getFullTitle(): string
    {
        // $this->getLocale() reflects the current locale being generated.
        return 'post-' . $this->getTranslation('title', $this->getLocale(), false);
    }
}

use Oliwol\Slugify\Events\SlugGenerated;
use Oliwol\Slugify\Events\SlugUpdated;

// In EventServiceProvider::$listen or via Event::listen()
Event::listen(SlugGenerated::class, function (SlugGenerated $event) {
    Log::info("Slug created: {$event->slug}", [
        'model' => get_class($event->model),
        'id' => $event->model->getKey(),
    ]);
});

Event::listen(SlugUpdated::class, function (SlugUpdated $event) {
    Log::info("Slug changed: {$event->oldSlug} → {$event->newSlug}", [
        'model' => get_class($event->model),
        'id' => $event->model->getKey(),
    ]);

    // Example: create a redirect entry
    Redirect::create([
        'from' => $event->oldSlug,
        'to' => $event->newSlug,
    ]);
});

use Oliwol\Slugify\Rules\SlugFormat;

'slug' => ['lugFormat(separator: '_')],

use Oliwol\Slugify\Rules\SlugRule;

// Basic — create scenario
public function rules(): array
{
    return [
        'slug' => ['g' => ['     '

'slug' => ['

// make() without withSlug — no slug
$post = Post::factory()->make(); // slug is null

// make() with withSlug — slug is generated
$post = Post::factory()->withSlug()->make(); // slug: "hello-world"

// Custom slug
$post = Post::factory()->withSlug('my-custom-slug')->make();

// Batch creation — slugs are unique
$posts = Post::factory()->count(3)->withSlug()->create();
// → "hello-world", "hello-world-2", "hello-world-3"

public function scopeSlugQuery($query)
{
    return $query->where('tenant_id', 1);
}
bash
php artisan vendor:publish --tag=slugify-config
bash
php artisan vendor:publish --tag=slugify-migrations
php artisan migrate
bash
php artisan vendor:publish --tag=slugify-config
bash
php artisan slugify:generate "App\Models\Post"
bash
php artisan slugify:generate "App\Models\Post" --force
bash
php artisan slugify:generate "App\Models\Post" --dry-run