7

I'm trying to convert cakephp 2.x to 3.x. I was using Router::connect() rules, but I try to convert them to scope version.

Regarding to myold routing rule, in config/routes.php I added this.

  Router::defaultRouteClass('Route');
  Router::scope('/', function ($routes) {

    $routes->connect('/:language/:controller/:action/*', ['language' => 'ar|de|en|fr']);
    $routes->connect('/:language/:controller', ['action' => 'index', 'language' => 'ar|de|en|fr']);
    $routes->connect('/:language', ['controller' => 'Mydefault', 'action' => 'index', 'language' => 'ar|de|en|fr']);

    $routes->redirect('/gohere/*', ['controller' => 'Mycontroller', 'action' => 'myaction'], ['persist' => array('username')]);

    $routes->connect('/', ['controller' => 'Mydefault', 'action' => 'index']);

    $routes->fallbacks('InflectedRoute');
});
  • But this fails in example.com/en/works. I get this error: Error: worksController could not be found. Because my controller file is WorksController.php.

Does controller name part hanged to sentence casein cakephp 3 ? http://book.cakephp.org/3.0/en/intro/conventions.html#controller-conventions

  • Also example.com/foo/bar gives this error: Error: barController could not be found.. But foo is controller and bar is action.

How can I fix this routing problem ?

Edit:
Changing Route::defaultRouteClass('Route') to Route::defaultRouteClass('InflectedRoute') solved problem 1. But problem 2 exists.

2
  • There must be a line Route::defaultRouteClass('Route') at top of your routes.php. Change it to Route::defaultRouteClass('InflectedRoute'). Commented Jul 12, 2015 at 13:27
  • This fixed error 1. But error 2 exists. When I enter example.com/foo/bar, cakephp looks for barController. Commented Jul 12, 2015 at 19:36

4 Answers 4

6
+50

Options, such as route element patterns, must be passed via the third argument of Router::connect(), the $options argument.

This route:

$routes->connect(
    '/:language/:controller',
    ['action' => 'index', 'language' => 'ar|de|en|fr'
]);

will catch your /foo/bar URL, it will match foo for the :language element, and bar for the :controller element. Basically the language key in the URL array will be treated as the default value, and it will always be overwritten by the :language element value.

The correct way of defining the route is:

$routes->connect(
    '/:language/:controller',
    ['action' => 'index'],
    ['language' => 'ar|de|en|fr']
);

The other routes need to be adapted accordingly.

See also Cookbook > Routing > Connecting Routes

Sign up to request clarification or add additional context in comments.

Comments

2

The best way is using Routing scopes

<?php
$builder = function ($routes) {
    $routes->connect('/:action/*');
};
$scopes = function ($routes) use ($builder) {
    $routes->scope('/questions', ['controller' => 'Questions'], $builder);
    $routes->scope('/answers', ['controller' => 'Answers'], $builder);
};

$languages = ['en', 'es', 'pt'];
foreach ($languages as $lang) {
    Router::scope("/$lang", ['lang' => $lang], $scopes);
}

Router::addUrlFilter(function ($params, $request) {
    if ($request->param('lang')) {
        $params['lang'] = $request->param('lang');
    }
    return $params;
});

Code taken from:

https://github.com/steinkel/cakefest2015/blob/c3403729d7b97015a409c36cf85be9b0cc5c76ef/cakefest/config/routes.php

Comments

0

Extending on default router from CakePHP 3 application skeleton

original routes.php removed comments

<?php

use Cake\Routing\RouteBuilder;
use Cake\Routing\Router;
use Cake\Routing\Route\DashedRoute;

Router::defaultRouteClass(DashedRoute::class);

Router::scope('/', function (RouteBuilder $routes) {
    $routes->applyMiddleware('csrf');
    $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
    $routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
    $routes->fallbacks(DashedRoute::class);
});

modified with language from defined set

<?php

use Cake\Routing\RouteBuilder;
use Cake\Routing\Router;
use Cake\Routing\Route\DashedRoute;

Router::defaultRouteClass(DashedRoute::class);

$routerCallback = function (RouteBuilder $routes) {
    $routes->applyMiddleware('csrf');
    $routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);
    $routes->connect('/pages/*', ['controller' => 'Pages', 'action' => 'display']);
    $routes->fallbacks(DashedRoute::class);
};

// support only for 3 languages, other language will throw 404/NotFoundException
// or will cause different routing problem based on your routes
Router::scope('/', $routerCallback);
foreach (["en", "fr", "de"] as $language) {
    Router::scope('/' . $language, ['language' => $language], $routerCallback);
}

// to access the language param, or default to 'en', use 
// $this->request->getParam('language', 'en')
// from AppController, PagesController, etc...

Comments

0

rooter.php

$routes->connect('/:lang/:controller/:action',[],[ 'lang' => '[a-z]{2}','pass' => ['lang']]);
$routes->connect('/:lang/', ['controller' => 'Pages', 'action' => 'index'],[ 'lang' => '[a-z]{2}','pass' => ['lang']]); 
$routes->connect('/:lang/index', ['controller' => 'Pages', 'action' => 'index'],[ 'lang' => '[a-z]{2}','pass' => ['lang']]); 
$routes->connect('/:lang/pages/*', ['controller' => 'Pages', 'action' => 'index'],[ 'lang' => '[a-z]{2}','pass' => ['lang']]);
$routes->connect('/:lang/contact', ['controller' => 'Pages', 'action' => 'contact'],[ 'lang' => '[a-z]{2}','pass' => ['lang']]);
$routes->connect('/:lang/about', ['controller' => 'Pages', 'action' => 'about'],[ 'lang' => '[a-z]{2}','pass' => ['lang']]);

Class Appcontroller public function beforeFilter(Event $event) { $this->Auth->allow(['']);

    if(isset($this->request->params['pass'][0]))
    $lang = $this->request->params['pass'][0];
    else $lang = 'en';
    I18n::locale($lang);

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.