I'm trying to load the VideoController.php when url.com/video/ is called.
Here is a piece of code from my routes.php
Router::scope('/', function (RouteBuilder $routes) {
$routes->connect('/video/*', ['controller' => 'Video', 'action' => 'display']);
...
$routes->fallbacks(DashedRoute::class);
});
The result is '404 not found'
EDIT:
Inside Router::scope I have also this piece of code:
$routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
When I change the Pages value into Video, the VideoController is called. So how come when I change the '/' into '/video/*' it doesn't work?
Maybe it's something with the scope function parameters?
Enabling URL rewriting from the httpd.config file solved the problem.
cakephp documentation
Related
I know POST method is pointing to add() in a controller as default in cakephp3. Is it possible to custom that and point POST method to index()? Something like below:
Router::connect(
'/test',
array(
'controller' => 'Test',
'action' => 'index',
'[method]' => 'POST'
)
);
Thanks to #ndm who made a very clear solution for my question.
One of my issue is that I have $routes->resources('Test'); which will disable #ndm's solutions. So first of all, I commented out the line $routes->resources('Test');.
Because of I'm not working on a solid project which is a temporary project for a narrowed purpose, so below code is working perfectly for me now.
Router::scope('/', function ($routes) {
$routes->setExtensions(['json']);
// $routes->resources('Test');
$routes->post(
'/test',
['controller' => 'Test', 'action' => 'add']
);
});
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();
Your 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().
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Cake\Http\ControllerFactory;
use Cake\Routing\Exception\MissingControllerException;
class _404Middleware {
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next)
{
//$params = (array)$request->getAttribute('params', []);
try {
$factory = new ControllerFactory();
$controller = $factory->create($request, $respond);
}
catch (\Cake\Routing\Exception\MissingControllerException $e) {
// here you fallback to your controllers/action or issue app level redirect
$request = $request->withAttribute('params',['controller' =>'brands','action' => 'index']);
}
return $next($request, $response);
}
}
Then attach in your App\Application see also attaching middlewares
$middlewareStack->add(new _404Middleware());
please 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.
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.
$routes->connect(':/prefix/:controller/:action/*', [], ['routeClass' => 'DashedRoute']);
And maybe another one without prefix
$routes->connect('/:controller/:action/*', [], ['routeClass' => 'DashedRoute']);
And since you mentioned that you are using 3.3.* cake version, Your routes can be written taking advatage of routes scoping
Router::prefix('website', function ($routes) {
// All routes here will be prefixed with `/prefix`
// And have the prefix => website route element added.
$routes->fallbacks(DashedRoute::class);
$routes->connect(
'/:slug',
['controller' => 'Brands', 'action' => 'index']
);
$routes->connect(
':slug/*',
['controller' => 'Products', 'action' => 'index']
});
CakePHP 3.0
I'm getting a "Missing Route" error for a route that exists.
Here are my routes:
#my admin routes...
Router::prefix('admin', function($routes) {
$routes->connect('/', ['controller'=>'Screens', 'action'=>'index']);
$routes->connect('/screens', ['controller'=>'Screens', 'action'=>'index']);
$routes->connect('/screens/index', ['controller'=>'Screens', 'action'=>'index']);
//$routes->fallbacks('InflectedRoute');
});
Router::scope('/', function ($routes) {
$routes->connect('/login', ['controller' => 'Pages', 'action' => 'display', 'login']);
$routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
$routes->fallbacks('InflectedRoute');
});
Plugin::routes();
Basically I just added the top section (for admin routing) to the default routes that come out of the box.
When I visit /admin/screens/index I see the following error:
Notice the error message says:
Error: A route matching "array ( 'action' => 'add', 'prefix' =>
'admin', 'plugin' => NULL, 'controller' => 'Screens', '_ext' => NULL,
)" could not be found.
...which is strange because I am not trying to access the add action. The params printed below look correct.
What is going on?
Take a closer look at the stacktrace, the error dosn't occour in the dispatching process, which you seem to think, it is being triggered in your view template, where you are probably trying to create a link to the add action, and reverse-routing cannot find a matching route, hence the error.
The solution should be obvious, connect the necessary routes, being it explicit ones like
$routes->connect('/screens/add', ['controller' => 'Screens', 'action' => 'add']);
catch-all ones
$routes->connect('/screens/:action', ['controller' => 'Screens']);
or simply the fallback ones that catch everything
$routes->fallbacks('InflectedRoute');
This work for me in case of use prefix admin :-
Router::prefix('admin', function ($routes) {
// Because you are in the admin scope,
// you do not need to include the /admin prefix
// or the admin route element.
$routes->connect('/', ['controller' => 'Users', 'action' => 'index']);
$routes->extensions(['json', 'xml']);
// All routes here will be prefixed with `/admin`
$routes->connect('/admin', ['controller' => 'Order', 'action' => 'index']);
// And have the prefix => admin route element added.
$routes->fallbacks(DashedRoute::class);
});
I am trying to connect /admin/ to a static page 'admin.ctp'.
I copied the pages controller for modification and copied the display function to admin_display. I also tried creating an admin_index function without parameters. My route looks like this at this moment:
Router::connect('/admin/', array('controller' => 'pages', 'action' => 'index', 'prefix' => 'admin'));
my admin_index function looks like this:
function admin_index() {
$page = 'admin';
$subpage = null;
$title_for_layout = 'Admin';
$this->set(compact('page', 'subpage', 'title_for_layout'));
$this->render('/admin');
}
I put admin.ctp in /views/pages/ and in /views/pages/admin/
Anyway. When I go to /admin/ it redirects me to /. But when I delete admin_index, it complains that the function does not exist, so I does look for it.
Help?
edit: Big correction, all my admin urls go back to /
edit2: resolved it, something with appcontroller :$
Create admin_index.ctp file in /views/pages/.
Remove $this->render('/admin'); from the admin_index function. (If you wanted to use admin.ctp, I think all you would have to do is to remove the / from the argument). There's no reason to render admin.ctp for admin_index, since it's natural for cake to render admin_index.ctp for admin_index function. You just don't gain anything by not doing that the cake way.
If it doesn't work, try
Router::connect('/admin/', array('controller' => 'pages', 'action' => 'index', 'prefix' => 'admin', 'admin' => true));
If you want to route /admin/*action* requests to pages controllers admin_action function, then add this line to routes.php:
Router::connect('/admin/:action/*', array('controller' => 'pages', 'prefix' => 'admin', 'admin' => true));
Router::connect('/admin/', array('controller' => 'pages', 'action' => 'index', 'admin')); would work with the standard pages controller
I have admin routing enabled. How can I set routing, to make http://website.com/admin go to posts/admin_index?
I've got this:
Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
But it doesn't seem to work. I get this error (when going to http://website.com/admin):
Missing Controller
Error: Controller could not be found.
Error: Create the class Controller below in file: app/controllers/controller.php
<?php
class Controller extends AppController {
var $name = '';
}
?>
Try a route with:
Router::connect('/admin', array('controller' => 'posts', 'action' => 'index', 'admin' => true));
The default route '/' does not match the URL '/admin', admin routing enabled or not.