Reputation: 1841
I have looked in quite a few places to no avail so I thought it was time to ask the experts.
I am playing about with laravel and I am having some issues with routing.
I have a cms of sorts and also a product catalogue, each of which uses no prefix to the pages.
A product might be 'example.com/my-product' and a page might be 'example.com/my-page'
In my routes I want to check if the url matches a page or a product or neither and then redirect to a specific controller/action depending on which it is.
currently I have
Route::any('/{slug}', function($slug) {
$page = App\Models\Page::firstByAttributes(['slug' => $slug]);
if($page) {
// go to pagesController@find
}
})->where('slug', '.*');
To differentiate between a page and a product is fine, I'll just pop an elseif after the if($page) for the product check but I am stumped as to how to get to the PagesController once I have determined that the url points to a page on the db.
Any help would be massively appreciated.
Edit:
My Pages Controller:
class PagesController extends BaseController {
public function find()
{
echo 'asdaasda'; die;
}
}
I can get this to work after a fashion but its not what I want. I need the url to remain as it was and the PagesController to handle the processing and rendering of the page. The only way I can get it to work is by adding a Route::controller('pages', 'PagesController') to the routes file then modifying the find function to getFind but that just ends up with a url that looks like example.com/pages/find/ rather than the original url that might have been something along the line of example.com/about-us.
Upvotes: 0
Views: 923
Reputation: 1841
I have no idea if this is super bad practice but the only way I can see to get around this issue is to do the following in routes.php.
$url = \URL::current();
$url = explode('/', $url);
$end = end($url);
if($page = App\Models\Page::firstByAttributes(['slug' => $end])) {
Route::get('/'.$end, 'PagesController@find');
} elseif($product = App\Models\Product::firstByAttributes(['slug' => $end])) {
Route::get('/'.$end, 'ProductsController@find');
}
This basically gets the final part of the url and then checks if we have a page with that url and add the route for that specific page, if not, it checks if we have a product that fits the url and adds the route for that product.
If anyone has a cleaner solution I would love to know. I can't imagine that laravel doesn't have a way of creating routes based on database pages without having to either prefix them all with something like "pages/page-url".
Upvotes: 0
Reputation: 5387
Try this
Route::any('/{slug}', function($slug) {
$page = App\Models\Page::firstByAttributes(['slug' => $slug]);
if($page) {
return Redirect::action('pagesController@find', array($page));
}
})->where('slug', '.*');
You can also consider using route filters to achieve this in a slightly more readable way.
Upvotes: 2