laravel получает динамическое представление на основе URL - PullRequest
0 голосов
/ 02 ноября 2018

Я создал динамические маршруты категорий, добавив в свое приложение пользовательский класс ( как я это сделал здесь ), теперь мне нужно, чтобы мой блейд работал с этим динамическим путем.

Logic

на основе категорий глубины, которые создаст мой URL, например:

site.com/category/parent
site.com/category/parent/child
site.com/category/parent/child/child
etc.

пока что мое представление просто загружается для site.com/category/parent для других URL, оно возвращает 404 ошибка.

код

CategoryRouteService

class CategoryRouteService
{
    private $routes = [];

    public function __construct()
    {
        $this->determineCategoriesRoutes();
    }

    public function getRoute(Category $category)
    {
        return $this->routes[$category->id];
    }

    private function determineCategoriesRoutes()
    {
        $categories = Category::all()->keyBy('id');

        foreach ($categories as $id => $category) {
            $slugs = $this->determineCategorySlugs($category, $categories);

            if (count($slugs) === 1) {
                $this->routes[$id] = url('category/' . $slugs[0]);
            }
            else {
                $this->routes[$id] = url('category/' . implode('/', $slugs));
            }
        }
    }

    private function determineCategorySlugs(Category $category, Collection $categories, array $slugs = [])
    {
        array_unshift($slugs, $category->slug);

        if (!is_null($category->parent_id)) {
            $slugs = $this->determineCategorySlugs($categories[$category->parent_id], $categories, $slugs);
        }

        return $slugs;
    }
}

CategoryServiceProvider

class CategoryServiceProvider
{
    public function register()
    {
        $this->app->singleton(CategoryRouteService::class, function ($app) {
            // At this point the categories routes will be determined.
            // It happens only one time even if you call the service multiple times through the container.
            return new CategoryRouteService();
        });
    }
}

model

//get dynamic slug routes
    public function getRouteAttribute()
    {
        $categoryRouteService = app(CategoryRouteService::class);

        return $categoryRouteService->getRoute($this);
    }

blade

//{{$categoryt->route}} returning routes
<a class="post-cat" href="{{$category->route}}">{{$category->title}}</a>

route

//show parent categories with posts
Route::get('/category/{slug}', 'Front\CategoryController@parent')->name('categoryparent');

controller

public function parent($slug){
        $category = Category::where('slug', $slug)->with('children')->first();
        $category->addView();
        $posts = $category->posts()->where('publish', '=', 1)->paginate(8);
        return view('front.categories.single', compact('category','posts'));
}

Примечание: Я не уверен в этом, но я думаю, что мой маршрут довольно статичен! Я имею в виду, что он получает только 1 пулю, в то время как моя категория может пройти 2, 3 или 4 пули, и для меня не имеет смысла проложить несколько маршрутов и продолжать повторять Route::get('/category/{slug}/{slug}/{slug} вот так.

Как я уже сказал, я не уверен в этом, пожалуйста, поделитесь своей идеей и решениями, если можете.

UPDATE

на основе Leena Patel ответа Я изменил свой маршрут, но когда я получаю более 1 пули в моем URL, возвращается ошибка:

Example

route: site.com/category/resources (works)

route: site.com/category/resources/books/ (ERROR)
route: site.com/category/resources/books/mahayana/sutra (ERROR)

error

Call to a member function addView() on null

на

$category->addView();

когда я комментирую, что он возвращает ошибку для $posts части. тогда ошибка для моего лезвия, где я возвратил название категории {{$category->title}}

Так что, по-видимому, эта функция не распознает возвращаемые виды маршрутов категории.

here is my function

public function parent($slug){
        $category = Category::where('slug', $slug)->with('children')->first();
        $category->addView();
        $posts = $category->posts()->where('publish', '=', 1)->paginate(8);
        return view('front.categories.single', compact('category','posts'));
}

есть идеи?

Ответы [ 3 ]

0 голосов
/ 02 ноября 2018

Создать маршрут

Route::get('category/{cat}', 'YourController@mymethod');

Добавьте это к способу загрузки вашего провайдера / RouteServiceProvider.php

public function boot()
{
    Route::pattern('cat', '.+'); //add this

    parent::boot();
}

В вашем методе:

public function mymethod($cat){
    echo $cat;  //access your route
}
0 голосов
/ 02 ноября 2018

Вы можете использовать дополнительные секции URL в маршруте и использовать условные выражения в контроллерах. Попробуйте это:

На вашем маршруте :

Route::get('/category/{parent?}/{child1?}/{child2?}', 'Front\CategoryController@parent')->name('categoryparent');

В вашем контроллере :

public function mymethod($category, $parent, $child1, $child2){
    if(isset($child2)){
        //use $category, $parent, $child1, $child2 and return view
    } else if(isset($child1)){
        //use $category, $parent, $child1 and return view
    } else if(isset($parent)){
        //use $category, $parent and return view
    } else {
        //return view for $category
    }

}
0 голосов
/ 02 ноября 2018

Вы можете попробовать использовать шаблон маршрута, как показано ниже

Route::get('/category/{slug}', 'Front\CategoryController@parent')->where('slug','.+')->name('categoryparent')

Так что, если у вас есть несколько слагов в вашем URL, например /category/slug1/slug2

Ваш метод addView() будет работать для one record, а не для Collection. Для этого добавьте цикл foreach.

public function parent($slug){
    // $slug  will be `slug1/slug2`
    $searchString = '/';
    $posts = array();

    if( strpos($slug, $searchString) !== false ) {
        $slug_array = explode('/',$slug);
    }

    if(isset($slug_array))
    {
         foreach($slug_array as $slug)
         {
             $category = Category::where('slug', $slug)->with('children')->first();
             $category->addView();
             $posts_array = $category->posts()->where('publish', '=', 1)->paginate(8);
             array_push($posts,$posts_array);
         }
    }
    else
    {
          $category = Category::where('slug', $slug)->with('children')->first();
          $category->addView();
          $posts = $category->posts()->where('publish', '=', 1)->paginate(8);
    }

    return view('front.categories.single', compact('category','posts'));
}

Надеюсь, это поможет!

Документация: https://laravel.com/docs/4.2/routing#route-parameters

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...