Reputation: 83
How can I handle 2 similar urls in my routes.php in Laravel Framework ?
Eg :
Code :
#Categories Pages
Route::get('{catSlug}', array('uses' => 'CategoriesController@show'));
#Product Page
Route::get('{productSlug}', array('uses' => 'ProductController@show'));
If i browse to mysite/shoes show method in CategoriesController is fired, but if I browse to mysite/adidas-model-1 it's not show method of ProductController but the one of CategoriesController which is fired.
Is there a nice way to achieve this in routes.php file ? Or do I route all to CategoriesController@show and if object is not found fire the show method of ProductController ?
Thanks.
Upvotes: 1
Views: 2685
Reputation: 2161
Try to make it like this, this is how I use it.
Route::get('{slug}', function($slug) {
// IF IS CATEGORY...
if($category = Category::where('slug', '=', $slug)->first()):
return View::make('category')
->with('category', $category);
// IF IS PRODUCT ...
elseif($product = Product::where('slug', '=', $slug)->first()):
return View::make('product')
->with('product', $product);
// NOTHING? THEN ERROR
else:
App::abort(404);
endif;
});
Upvotes: 0
Reputation: 83
Thanks for your answers.
I really need to be free of what I choose for my slugs. So i found an other solution.
# Objects (cats or products)
Route::get('{slug}', array('uses' => 'BaseController@route'));
and in my BaseController file :
public function route($slug)
{
// Category ?
if($categories = Categories::where('slug', '=', $slug)->first()){
return View::make('site/categories/swho', compact('categories'));
// Product ?
}elseif($products = Products::where('slug', '=', $slug)->first()){
return View::make('site/products/show', compact('products'));
}
}
I first test for a Category object (I have less categories than products) and if not found I test for a product.
Upvotes: 1
Reputation: 15750
In the two routes you've shown, the router has no way of knowing when you're entering a catSlug
and when you're entering a productSlug
- they're both strings and there's no code there to distinguish them.
You can correct this by adding a where
clause:
Route::get('{catSlug}', array('uses' => 'CategoriesController@show'))
->where('catSlug', '[A-Za-z]+');
Route::get('{productSlug}', array('uses' => 'ProductController@show'))
->where('productSlug', '[-A-Za-z0-9]+');
In the regular expressions above, I've assumed that categories are strings of upper and lower case letters only - no numbers, no spaces, no punctuation - and products include hyphens and numbers.
I should also add that the order of these declarations will be important. The product route also matches the category route, so the category route should be declared first, so it has a chance to fire. Otherwise, everything looks like a product.
Upvotes: 2