CakePHP 4 - 带有 i18n 语言参数的管理员前缀路由

问题描述

我有 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。

解决方法

部分完成
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('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());
    }
}
,

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

话虽如此,您正在使用前缀内的 :language 元素连接路由,因此您的 URL 不能是 /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('/','action' => 'login'])
            ->setPatterns($patterns);
    });
});

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...