Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

laravelio/laravel.io

2497 stars
4 code files
View laravelio/laravel.io on GitHub

app/Helpers/HasSlug.php

Open in GitHub
// There's a mismatch with the folder name of "Helpers", but these are not global helpers, they are Traits
 
namespace App\Helpers;
 
trait HasSlug
{
public function slug(): string
{
return $this->slug;
}
 
public function setSlugAttribute(string $slug)
{
$this->attributes['slug'] = $this->generateUniqueSlug($slug);
}
 
public static function findBySlug(string $slug): self
{
return static::where('slug', $slug)->firstOrFail();
}
 
private function generateUniqueSlug(string $value): string
{
$slug = $originalSlug = Str::slug($value) ?: Str::random(5);
$counter = 0;
 
while ($this->slugExists($slug, $this->exists ? $this->id() : null)) {
$counter++;
$slug = $originalSlug.'-'.$counter;
}
 
return $slug;
}
 
private function slugExists(string $slug, int $ignoreId = null): bool
{
$query = $this->where('slug', $slug);
 
if ($ignoreId) {
$query->where('id', '!=', $ignoreId);
}
 
return $query->exists();
}
}

app/Models/Tag.php

Open in GitHub
use App\Helpers\HasSlug;
 
final class Tag extends Model
{
use HasSlug;
 
// ... other Model code
}

app/Models/Article.php

Open in GitHub
use App\Helpers\HasSlug;
 
final class Article extends Model
{
use HasSlug;
 
// ... other Model code
}

routes/bindings.php

Open in GitHub
// This file overrides the default Laravel Route Model Binding with other rules
// including findBySlug() that comes from the HasSlug Trait
 
Route::bind('tag', function (string $slug) {
return App\Models\Tag::findBySlug($slug);
});
Route::bind('article', function (string $slug) {
return App\Models\Article::findBySlug($slug);
});

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.