Using CakePHP v3.3.16
I want to write a fallback route in such a way that if URL is not connected to any action then it should go to that fallback.
Created routes for SEO friendly URL like this
$routes->connect(
':slug',
['prefix'=>'website','controller' => 'Brands', 'action' => 'index'],
['routeClass' => 'DashedRoute']
);
$routes->connect(
':slug/*',
['prefix'=>'website','controller' => 'Products', 'action' => 'index'],
['routeClass' => 'DashedRoute']
);
But it’s also inclute all the controller actions in it so if i try to call a controller ex: cart/index it’s going to website/brands/index/index
If I have to remove exclude it, I have to create a route like this/
$routes->connect('/cart',['controller' => 'Cart'], ['routeClass' => 'DashedRoute']);
And so on to the other controller to access.
Example:
I have a controller CartController action addCart
CASE 1
if I access URL my_project/cart/addCart/
It should go to cart controller action
CASE 2
if I access URL my_project/abc/xyz/
and there is no controller named abc so it should go to BrandsController action index
My Current routes.php looks like this
Router::defaultRouteClass(DashedRoute::class);
Router::scope('/', function (RouteBuilder $routes) {
$routes->connect('/', ['prefix'=>'website','controller' => 'Home', 'action' => 'index']);
$routes->connect('/trending-brands', ['prefix'=>'website','controller' => 'Brands', 'action' => 'trending']);
$routes->connect('/users/:action/*',['prefix'=>'website','controller' => 'Users'], ['routeClass' => 'DashedRoute']);
$routes->connect('/cart',['prefix'=>'website','controller' => 'Cart'], ['routeClass' => 'DashedRoute']);
$routes->connect('/cart/:action/*',['prefix'=>'website','controller' => 'Cart'], ['routeClass' => 'DashedRoute']);
$routes->connect(
':slug',
['prefix'=>'website','controller' => 'Brands', 'action' => 'index'],
['routeClass' => 'DashedRoute']
);
$routes->connect(
':slug/*',
['prefix'=>'website','controller' => 'Products', 'action' => 'index'],
['routeClass' => 'DashedRoute']
);
$routes->connect(':controller', ['prefix'=>'website'], ['routeClass' => 'DashedRoute']);
$routes->connect(':controller/:action/*', ['prefix'=>'website'], ['routeClass' => 'DashedRoute']);
$routes->fallbacks(DashedRoute::class);
});
Router::prefix('website', function (RouteBuilder $routes) {
$routes->fallbacks(DashedRoute::class);
});
Plugin::routes();
2
Answers
If I have to remove exclude it, I have to create a route like this/ And so on to the other controller to access.
There is no need to specify every controller/name in the pattern, instead you can create all your specify routes first and then place the following route below them to catch all unmatched routes.
And maybe another one without prefix
And since you mentioned that you are using
3.3.*
cake version, Your routes can be written taking advatage of routes scopingYour edits totally invalidate my first answer, so I decided to just post another answer.
What you want to achieve can not be done by the router because there is no way for router to tell if the controller/action exists for a particular route. This is because the router just work with url templates and delegates the task of loading Controllers up in the request stack.
You can emulate this feature though by using a Middleware
that check if the request attribute
params
is set and then validate them as appropriate and changing them to your fallback controller if the target controller doesn’t exist.Just make sure to place the
RoutingMiddleware
execute before your middleware otherwise you will have no params to check because the routes wouldn’t have been parsed.Middlewares implement one method
__invoke()
.Then attach in your
AppApplication
see also attaching middlewaresplease remmber to clean up the code as I didn’t test it under real dev’t enviroment.
After thought: if your were looking to create an error page for all not found resources, then you don’t need all that, instead you would just customise the error template in
Template/Error/error404.ctp
.