Laravel Slugs with Str::slug

Посмотрите на Str::slug для генерации моего внешнего URL-адреса, но просто удивляетесь, как вы, ребята, реализуете его с помощью маршрутов и т. Д., Например, как бы вы, ребята, поменяли http://www.example.com/courses/1 на http://www.example.com/courses/this-course

6 ответов

Решение

ОК, я сделал это так:

// 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);
});

Работает как шарм. Он получает переменные $categorySlug и $slug, а затем использует их для фильтрации курса Eloquent модели, чтобы получить правильный объект курса из базы данных.

РЕДАКТИРОВАТЬ: Вы можете создать URL в вашем представлении, как:

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

Делая что-то вроде:

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

У меня есть метод в моей категории, как показано ниже, который получает слаг родительской категории. Этого можно добиться лучше, используя некоторый класс презентатора, который позволит вам просто использовать $course->url, но я пока не успел это сделать. Я обновлю ответ, когда я сделаю.

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

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

Вы можете использовать пакет Eloquent-Sluggable cvierbrock.

Что касается меня, я создал вспомогательную функцию и использовал следующий метод, взятый отсюда.

 public static function getSlug($title, $model) {
    $slug = Str::slug($title);
    $slugCount = count( $model->whereRaw("url REGEXP '^{$slug}(-[0-9]*)?$'")->get() );
    return ($slugCount > 0) ? "{$slug}-{$slugCount}" : $slug;
}

Вы можете создать связанную модель Slug и подходить к курсу в ваших методах следующим образом:

$course = Slug::where('slug', $slug) -> firstOrFail() -> course;

Я также реализовал аналогичное сопоставление URL-адресов, но предпочел, чтобы в запрошенном URL-адресе были и идентификатор, и фрагмент:

http://www.example.com/courses/1/my-laravel-course

Этот метод позволяет мне получить запрошенный course объект из идентификатора, указанного в URL, вместо того, чтобы хранить слагов в моей таблице БД.

Route::post('courses/(:num)/(:any)', function ($courseid, $slug) {
    $course = Course::where('id', '=', $courseid)->get();
    return View::make('courses.show')->with('course', $course);
}

Для Ларавель 8:

Учитывая мой URL:

      http://www.example.com/courses/this-course

Мой маршрут:

      Route::get('/courses/{course:slug}' , function(Course $course){
     return view('showCourse' , [
         'course' => $course
     ])
})
Другие вопросы по тегам