2

I am trying to use prefix routing in CakePHP3. I added the following lines to /config/routes.php.

Router::prefix("admin", function($routes) {
    // All routes here will be prefixed with ‘/admin‘
    // And have the prefix => admin route element added.
    $routes->connect("/",["controller"=>"Tops","action"=>"index"]);
    $routes->connect("/:controller", ["action" => "index"]);
    $routes->connect("/:controller/:action/*");
});

After that, I created /src/Controller/Admin/QuestionsController.php like below.

<?php
     namespace App\Controller\Admin;
     use App\Controller\AppController;

     class QuestionsController extends AppController {
        public function index() {
        //some code here
        }
     }
?>

Finally I tried to access localhost/app_name/admin/questions/index, but I got an error saying, Error: questionsController could not be found. However, when I capitalize the first letter of controller name(i.e. localhost/app_name/admin/Questions/index), it is working fine. I thought it is weird because without prefix, I can use controller name whose first character is not capitalized. Is this some kind of bug?

hitochan
  • 1,028
  • 18
  • 34

1 Answers1

10

In Cake 3.x, routes do not inflect by default anymore, instead you'll have to explicitly make use of the InflectedRoute route class, as can for example bee seen in the default routes.php app configuration:

Router::scope('/', function($routes) {
    // ...

    /**
     * Connect a route for the index action of any controller.
     * And a more general catch all route for any action.
     *
     * The `fallbacks` method is a shortcut for
     *    `$routes->connect('/:controller', ['action' => 'index'], ['routeClass' => 'InflectedRoute']);`
     *    `$routes->connect('/:controller/:action/*', [], ['routeClass' => 'InflectedRoute']);`
     *
     * You can remove these routes once you've connected the
     * routes you want in your application.
     */
    $routes->fallbacks();
});

You custom routes do not specify a specific route class, so the default Route class is being used, while the fallback routes make use of inflected routing, and that is why it's working without prefix.

So either use capitalized controller names in your URL, or use a route class like InflectedRoute that transforms them properly:

Router::prefix('admin', function($routes) {
    // All routes here will be prefixed with ‘/admin‘
    // And have the prefix => admin route element added.
    $routes->connect(
        '/',
        ['controller' => 'Tops', 'action' => 'index']
    );
    $routes->connect(
        '/:controller',
        ['action' => 'index'],
        ['routeClass' => 'InflectedRoute']
    );
    $routes->connect(
        '/:controller/:action/*',
        [],
        ['routeClass' => 'InflectedRoute']
    );
});

See also http://book.cakephp.org/3.0/en/development/routing.html#route-elements

ndm
  • 59,784
  • 9
  • 71
  • 110