【问题标题】:CakePHP 4 - Admin prefix routing with i18n language parameterCakePHP 4 - 带有 i18n 语言参数的管理员前缀路由
【发布时间】:2021-08-25 12:15:43
【问题描述】:

我有 cakephp4.2 项目,我已经实现了多语言方法,其中当前语言在会话中 sept。所有语言的网址都相同。

我也想在 url 中添加语言参数。我在config/routes.php 文件中尝试了以下代码,它适用于普通(非管理员前缀)网址。但不适用于Admin 前缀网址。

use Cake\Routing\RouterBuilder;

$routes->setRouteClass(DashedRoute::class);

$routes->scope('/', function (RouteBuilder $builder) {
    $builder->connect('/', ['controller' => 'Clients', 'action' => 'index']);

    $builder->connect('/:language/:controller/:action/*', array(), array('language' => 'en|ar'));
    $builder->connect('/:language/:controller', array('action' => 'index'), array('language' => 'en|ar'));
    $builder->connect('/:language', array('controller' => 'Clients', 'action' => 'index'), array('language' => 'en|ar')) ;

    $builder->fallbacks();
});

$routes->prefix('Admin', function (RouteBuilder $routes) {
    $routes->connect('/', ['controller' => 'Users', 'action' => 'login']);
    //added below line for language but it is not working
    //$routes->connect('/:language', array('controller' => 'Users', 'action' => 'login'), array('language' => 'en|ar')) ;
    $routes->fallbacks(DashedRoute::class);
});

工作网址

localhost/cake4-lng/     
localhost/cake4-lng/en    
localhost/cake4-lng/ar    
localhost/cake4-lng/en/controller    
localhost/cake4-lng/admin/users/dashboard /*notice there is no language param with Admin*/

无效的网址

localhost/cake4-lng/en/admin/users/dashboard    
localhost/cake4-lng/ar/admin/users/dashboard    

以上 2 个网址的错误是:

找不到AdminController。

【问题讨论】:

  • 配置中注释掉的管理路由仅适用于 login 操作,但您的示例 URL 列表中提到了 dashboard 操作。
  • 我的项目中有任何控制器和操作,我想要一些我为非管理员前缀所做的通用操作
  • 我不是路由专家,所以对此我无能为力。我只是想知道您的dashboard URL 不起作用的原因是否是因为您没有为它设置管理路由,仅用于login

标签: cakephp routes internationalization cakephp-4.x


【解决方案1】:

部分完成
URL 现在使用语言参数,但链接没有使用 HTML 帮助程序填充语言参数。 例如。

echo $this->Html->link('test',['controller'=>'clients','action'=>'index']);
生成html如下,不带语言参数
<a href="/clients/index">test</a>
当我需要的时候 <a href="/en/clients/index">test</a><a href="/ar/clients/index">test</a>

我在 routes.php 中添加了以下代码用于管理路由

$routes->prefix('Admin', function (RouteBuilder $routes) {
    $routes->connect('/:language', array('controller' => 'Users', 'action' => 'login'), array('language' => 'en|ar')) ;
    $routes->connect('/:language/:controller', array('action' => 'index'), array('language' => 'en|ar'));
    $routes->connect('/:language/:controller/:action/*', array(), array('language' => 'en|ar'));

    $routes->connect('/', ['controller' => 'Users', 'action' => 'login']);
    //$routes->connect('/:language', array('controller' => 'Users', 'action' => 'login'), array('language' => 'en|ar')) ;
    $routes->fallbacks(DashedRoute::class);
});

在 appCotroller.php 中

public function beforeFilter(EventInterface $event){       
    parent::beforeFilter($event); 
    $Session = $this->request->getSession(); 
    $urlLang = $this->request->getParam('language');
    if($urlLang!=null && in_array(strtolower($urlLang),['en','ar'])){
        $lng_val = strtolower($urlLang)=='ar'?'ar_AE':'en_us';
        $Session->write('Config.language',$lng_val);
    } 
    if($Session->check('Config.language')){
        I18n::setLocale($Session->read('Config.language'));
    }else{
        $Session->write('Config.language','ar_AE');
    } 
}

public function changeLanguage($language=null){
    $Session = $this->request->getSession(); 
    if($language!=null && in_array($language,['en_US','ar_AE'])){
        $Session->write('Config.language',$language);
        return $this->redirect($this->referer());
    }
    else
    {
        $Session->write('Config.language',I18n::locale());
        return $this->redirect($this->referer());
    }
}

【讨论】:

    【解决方案2】:

    首先,当您遇到路由问题时,请检查bin/cake routes 以查看哪些路由以哪种方式准确连接。

    话虽如此,您正在使用前缀内的:language 元素连接路由,因此您的网址不能是/en/admin/...,而只能是/admin/en/...。为了实现前者,您必须相应地将前缀包装在具有语言元素的范围内,类似于以下内容:

    $routes->scope('/:language', function (RouteBuilder $routes) {
        $routes->prefix('Admin', function (RouteBuilder $routes) {
            $patterns = ['language' => 'en|ar'];
            
            $routes
                ->connect('/:controller/:action/*', [])
                ->setPatterns($patterns);
            $routes
                ->connect('/:controller', ['action' => 'index'])
                ->setPatterns($patterns);
            $routes
                ->connect('/', ['controller' => 'Users', 'action' => 'login'])
                ->setPatterns($patterns);
        });
    });
    

    这将导致像 /:language/admin/... 这样的模板被连接。

    【讨论】:

    • 它说 Undefined variable: routes on line $routes->prefix('Admin', function (RouteBuilder $builder) {
    • 现在它说:缺少路由`匹配“数组的路由('prefix' => 'Admin', 'controller' => 'Users', 'action' => 'login', 'plugin ' => NULL, '_ext' => NULL, )" 找不到。`
    • 我在该数组中看不到language 键,所以我会说该错误是意料之中的,并且 URL 数组不正确。
    • 密码上下文是['_scheme' => 'http', '_host' => 'localhost', '_port' => null, '_base' => '/alampk4lng', 'params' => [ 'language' => 'ar', 'controller' => 'Admin', 'pass' => [ ], 'action' => 'index', 'plugin' => null, '_matchedRoute' => '/:language/:controller', '_ext' => null, ],]
    • 我不确定上下文与它有什么关系,或者错误的确切来源。检查堆栈跟踪以确定问题的确切触发位置,我仍然怀疑缺少 language 键的 URL 数组(params 是不同的东西,这是解析的结果,而不是正在匹配的东西)。
    猜你喜欢
    • 1970-01-01
    • 2011-01-03
    • 2016-06-17
    • 2015-09-30
    • 1970-01-01
    • 2015-12-24
    • 2013-01-05
    • 1970-01-01
    • 2013-05-29
    相关资源
    最近更新 更多