带有语言参数的 Cakephp 3 路由
Cakephp 3 routing with language parameter
我正在尝试将 cakephp 2.x 转换为 3.x。我正在使用 Router::connect()
规则,但我尝试将它们转换为范围版本。
关于我的旧路由规则,在 config/routes.php
我添加了这个。
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');
});
- 但这在
example.com/en/works
中失败了。我收到此错误:Error: worksController could not be found.
因为我的控制器文件是 WorksController.php
.
controller name 部分是否挂在casein cakephp 3 上? http://book.cakephp.org/3.0/en/intro/conventions.html#controller-conventions
- 也
example.com/foo/bar
给出了这个错误:Error: barController could not be found.
。但是 foo
是控制器而 bar
是行动。
我该如何解决这个路由问题?
编辑:
将 Route::defaultRouteClass('Route')
更改为 Route::defaultRouteClass('InflectedRoute')
解决了问题 1。但问题 2 存在。
选项,例如路由元素模式,必须通过 Router::connect()
的第三个参数,即 $options
参数传递。
这条路线:
$routes->connect(
'/:language/:controller',
['action' => 'index', 'language' => 'ar|de|en|fr'
]);
将捕获您的 /foo/bar
URL,它将匹配 foo
的 :language
元素,以及 bar
的 :controller
元素.基本上 URL 数组中的 language
键将被视为默认值,并且它将始终被 :language
元素值覆盖。
定义路线的正确方法是:
$routes->connect(
'/:language/:controller',
['action' => 'index'],
['language' => 'ar|de|en|fr']
);
其他路线需要相应调整。
最好的方法是使用路由范围
<?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;
});
代码取自:
在 CakePHP 3 应用程序框架的默认路由器上扩展
原创 routes.php 已删除评论
<?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);
});
使用定义集中的语言进行了修改
<?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...
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 应用程序控制器
public 函数 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);
}
我正在尝试将 cakephp 2.x 转换为 3.x。我正在使用 Router::connect()
规则,但我尝试将它们转换为范围版本。
关于我的旧路由规则,在 config/routes.php
我添加了这个。
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');
});
- 但这在
example.com/en/works
中失败了。我收到此错误:Error: worksController could not be found.
因为我的控制器文件是WorksController.php
.
controller name 部分是否挂在casein cakephp 3 上? http://book.cakephp.org/3.0/en/intro/conventions.html#controller-conventions
- 也
example.com/foo/bar
给出了这个错误:Error: barController could not be found.
。但是foo
是控制器而bar
是行动。
我该如何解决这个路由问题?
编辑:
将 Route::defaultRouteClass('Route')
更改为 Route::defaultRouteClass('InflectedRoute')
解决了问题 1。但问题 2 存在。
选项,例如路由元素模式,必须通过 Router::connect()
的第三个参数,即 $options
参数传递。
这条路线:
$routes->connect(
'/:language/:controller',
['action' => 'index', 'language' => 'ar|de|en|fr'
]);
将捕获您的 /foo/bar
URL,它将匹配 foo
的 :language
元素,以及 bar
的 :controller
元素.基本上 URL 数组中的 language
键将被视为默认值,并且它将始终被 :language
元素值覆盖。
定义路线的正确方法是:
$routes->connect(
'/:language/:controller',
['action' => 'index'],
['language' => 'ar|de|en|fr']
);
其他路线需要相应调整。
最好的方法是使用路由范围
<?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;
});
代码取自:
在 CakePHP 3 应用程序框架的默认路由器上扩展
原创 routes.php 已删除评论
<?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);
});
使用定义集中的语言进行了修改
<?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...
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 应用程序控制器 public 函数 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);
}