Laravel Slugs with Str::slug

Gareth Daine picture Gareth Daine · Jul 1, 2013 · Viewed 29.7k times · Source

Looking at Str::slug for my frontend URL generation but just wondering how you guys go about implementing it with routes etc, for example, how would you guys go about changing http://www.example.com/courses/1 to http://www.example.com/courses/this-course

Answer

Gareth Daine picture Gareth Daine · Jul 1, 2013

OK, I did it this way:

// I have a slug field in my courses table and a slug field in my categories table, along with a category_id field in my courses table.

// Route 

Route::get('courses/{categorySlug}/{slug?}', function($categorySlug, $slug) {
    $course = Course::leftJoin('categories', 'categories.id', 'courses.category_id')
        ->where('categories.slug', $categorySlug)
        ->where('courses.slug', $slug)
        ->firstOrFail();

    return View::make('courses.show')->with('course', $course);
});

Works like a charm. It gets the $categorySlug and $slug variables then uses them to filter the Eloquent model Course to get the correct course object from the database.

EDIT: You can generate a URL in your view like:

http://www.example.com/courses/it-training/mcse

By doing something like:

<a href="{{ URL::to('courses/'.$course->category->parentCategorySlug($course->category->parent_id).'/'.$course->category->slug.'/'. $course->slug) }}" title="{{ $course->title }}">{{ $course->title }}</a>

A have a method in my Category like below that retrieves the parent category slug. This could be better achieved though using some sort of presenter class which would allow you to simply use $course->url but I haven't got around to doing this yet. I will update the answer when I do.

public function parentCategorySlug($parentId)
{
    if ($parentId === '0')
    {
        return $this->slug;
    }

    return $this->where('id', $parentId)->first()->slug;
}