Laravel routing varying

后端 未结 1 1917
不知归路
不知归路 2021-01-22 18:24

I have a categories table that looks like this:

-- id   -- parent_id             -- name
    1             0              electronics
    2             1                 


        
相关标签:
1条回答
  • 2021-01-22 18:52

    I propose you change your URLs so they have a part that will be used for routing and one that will be used for SEO purposes. Here's what I mean:

    /products/view/{product_id}/{category_name}/{category_name}/{etc}/{product_name}
    /products/category/{category_id}/{category_name}/{category_name}/{etc}
    

    This has the advantage that you can ignore the fact that you won't always have the same numbers of categories. Your routing only depends on the first few segments of the URL.

    Route::get('products/view/{id}/{seo-slug?}', array('as' => 'product', function($id, $seoSlug){
        $product = Product::find($id);
        // ...
    }))->where('seo-slug', '.*');
    
    Route::get('products/category/{id}/{seo-slug?}', array('as' => 'category', function($id, $seoSlug){
        $category = Category::find($id);
        // ...
    }))->where('seo-slug', '.*');
    

    Now when it comes to generating links you will have a hard time just using Laravels helper functions. Let's create our own. One way is to add a function to the Product and Category models. (You could also write a function that's independent of the models, the core functionality stays the same)

    Product

    public function getUrl(){
        $categoryNames = array('cat1', 'cat2', 'cat3'); // use/create a function on the category model that uses recursion to determine all the categories of the tree
        $seoSlug = implode('/', $categoryNames);
        // ... maybe add other stuff to $seoSlug
        return route('product', array($this->id, $seoSlug));
    }
    

    Category

    public function getUrl(){
        $categoryNames = array('cat1', 'cat2', 'cat3'); // use the same function as above
        $seoSlug = implode('/', $categoryNames);
        // ... maybe add other stuff to $seoSlug
        return route('category', array($this->id, $seoSlug));
    }
    

    Redirect "wrong" URLs

    If you want, you can now redirect URLs that have a wrong SEO slug. Meaning it would also be possible to just enter:

    /products/view/183
    

    This can also serve as some kind of URL shortening for sending links in emails etc.

    To validate the URL and then redirect you can just compare the current URL with a "freshly" generated one. Like this:

    Route::get('products/view/{id}/{seo-slug?}', array('as' => 'product', function($id, $seoSlug){
        $product = Product::find($id);
        $productUrl = $product->getUrl()
        if(Request::url() !== $productUrl){
            return Redirect::to($productUrl);
        }
        // ...
    }))->where('seo-slug', '.*');
    

    Oh and Merry late Christmas to you too!

    0 讨论(0)
提交回复
热议问题