Normally we use post id to show a single post in Laravel. But it’s not SEO-friendly. So I’m going to write a post, on how you can generate a custom slug/URL for every post in your Laravel application. At first, the table field name should be a slug, and the form field name should be the title.
You’ve written the code into your Post model. It’s a first technique. It’ll generate slug like: lorem-ipsum, lorem-ipsum-1, lorem-ipsum-2
/** * Boot the model. */ protected static function boot(){ parent::boot(); static::created(function ($post) { $post->update(['slug' => $post->title]); }); } /** * Set the proper slug attribute. * * @param string $value */ public function setSlugAttribute($value){ if (static::whereSlug($slug = Str::slug($value))->exists()) { $slug = $this->incrementSlug($slug); } $this->attributes['slug'] = $slug; } /** * Increment slug * * @param string $slug * @return string **/ public function incrementSlug($slug) { // get the slug of the latest created post $max = static::whereTitle($this->title)->latest('id')->skip(1)->value('slug'); if (is_numeric($max[-1])) { return pred_replace_callback('/(\d+)$/', function ($mathces) { return $mathces[1] + 1; }, $max); } return "{$slug}-2"; }
Second technique. It’ll generate a slug with your post id, like lorem-ipsum-18
/** * Boot the model. */ protected static function boot(){ parent::boot(); static::created(function ($post) { $post->update(['slug' => $post->title]); }); } /** * Set the proper slug attribute * * @param string $value */ public function setSlugAttribute($value){ if (static::whereSlug($slug = Str::slug($value))->exists()) { $slug = "{$slug}-{$this->id}"; } $this->attributes['slug'] = $slug;
