Laravel基于URL获取动态视图

时间:2018-11-02 03:39:13

标签: php laravel

我已经通过向我的应用(how i did it is here)中添加自定义类来创建动态类别路由,现在我需要使我的刀片服务器可以使用此动态路径。

逻辑

基于我的网址将创建的类别的深度,例如:

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

到目前为止,我的视图只为site.com/category/parent加载其他网址,它返回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}毫无意义。

正如我说的那样,我不确定,请分享您的想法和解决方案。

更新

基于Leena Patel的答案,我更改了路线,但是当我的网址中收到超过1条子弹时,它将返回错误:

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 :(得分:1)

您可以尝试使用以下路由模式

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

因此,如果您的网址中有多个标签,例如/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

答案 1 :(得分:0)

创建路线

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

将此添加到您的Providers / RouteServiceProvider.php的启动方法

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

    parent::boot();
}

使用您的方法:

public function mymethod($cat){
    echo $cat;  //access your route
}

答案 2 :(得分:0)

您可以在路由中使用可选的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
    }

}