Yii2 根据所选语言更改控制器和动作名称
Yii2 change controller and action name acording to language selected
是否可以使用当前选择的语言更改控制器名称和操作名称,例如:
如果当前语言是 en 那么 url shuold:
http://localhost/yii2app/site/index
如果当前语言是 da 那么 url 应该:
http://localhost/yii.../websted/indeks
It is what I have tried but it shows 404 not found:
frontend/config/main.php
'urlManager' => [
'baseUrl' => $baseUrl,
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
Yii::t('app','site/index') => Yii::t('app','site/index'),
],
],
在common/messages/da/app.php
return [
'site/index'=>'websted/indeks'
];
在我的layouts/main.php
<a href="<?= Yii::$app->urlManager
->createUrl([Yii::t('app','site/index')])?>">
<?= Yii::t('app','Home') ?>
</a>
您的代码没有 运行 因为当 yii2 加载您的配置时,它没有 Yii
个实例。
对于您的问题,我有 2 个想法。希望有用。
1:使用redirect
示例:
public function actionIndex()
{
if(Yii::$app->language === 'da')
return $this->redirect(['websted/indeks']);
else
return $this->redirect(['site/index']);
}
当用户请求 site/index
时,yii 将根据您的语言重定向到其他 link。当语言为 da
时,浏览器中的地址将更改为 @baseUrl/websted/indeks
。但是,只要您的应用程序中有新语言,您就必须定义和更改代码。
2。将 rule
设为 bootstrap
配置:
'bootstrap' => [
'log',
[
'class' => 'app\components\Bootstrap',
],
],
Bootstrap.php
namespace app\components;
use Yii;
use yii\base\BootstrapInterface;
class Bootstrap implements BootstrapInterface
{
public function bootstrap($app)
{
$app->urlManager->addRules(['site/test' => Yii::t('app','site/test')]);
}
}
语言 1,app.php
return [
'site/test'=>'site/test1',
];
语言 2,app.php
return [
'site/test'=>'site/test2',
];
控制器(示例SiteController
):
public function actionTest1()
{
echo 1;
}
public function actionTest2()
{
echo 2;
}
但问题是:当用户请求 site/test
时,yii 会检查语言和 运行 操作 test1
或 test2
,而您浏览器中的地址只有 @baseUrl/site/test
.
祝你好运,玩得开心!
我已经修改了 Yii 论坛中的这段代码以适用于当前的框架版本。它需要进行测试,因为我很确定那里没有涵盖所有案例。
common\components\UrlManager.php:
<?php
namespace common\components;
use Yii;
use yii\web\Request;
use yii\web\UrlManager as YiiUrlManager;
/**
* UrlManager
* Allows to translate urls dynamically.
*/
class UrlManager extends YiiUrlManager
{
public $enablePrettyUrl = true;
public $showScriptName = false;
public $language;
/**
* Translated controllers names.
* language code => [
* source name => translated name
* ]
* @var array
*/
public $languageControllers = [
'eo' => [
'site' => 'ejo',
'users' => 'uzantoj'
],
];
/**
* Translated actions names.
* language code => [
* source name => translated name
* ]
* @var array
*/
public $languageActions = [
'eo' => [
'contact' => 'kontakton',
'about' => 'pri-ni',
'test' => 'testo'
],
];
/**
* Initializes UrlManager.
*/
public function init()
{
parent::init();
if (empty($this->language)) {
$this->language = Yii::$app->language;
}
}
/**
* Creates translated url.
* @param array $params
* @return string the created URL
*/
public function createUrl($params)
{
$params = (array)$params;
$route = explode('/', trim($params[0], '/'));
if (isset($route[0]) && !empty($this->languageControllers[$this->language][$route[0]])) {
$route[0] = $this->languageControllers[$this->language][$route[0]];
}
if (isset($route[1]) && !empty($this->languageActions[$this->language][$route[1]])) {
$route[1] = $this->languageActions[$this->language][$route[1]];
}
$params[0] = implode('/', $route);
return parent::createUrl($params);
}
/**
* Translates the request back to the source one.
* @param Request $request the request component
* @return Request
*/
public function translateRequest($request)
{
if (empty($this->languageControllers[$this->language])) {
return $request;
}
$url = ltrim($request->getPathInfo(), '/');
$parts = explode('/', $url);
$controller = $parts[0];
$action = isset($parts[1]) ? $parts[1] : null;
foreach ($this->languageControllers[$this->language] as $default => $localized) {
if ($localized == $controller) {
$controller = $default;
break;
}
}
$parts[0] = $controller;
if ($action !== null) {
foreach ($this->languageActions[$this->language] as $default => $localized) {
if ($localized === substr($action, 0, mb_strlen($localized, 'UTF-8'))) {
$action = $default . substr($action, mb_strlen($localized, 'UTF-8'));
break;
}
}
$parts[1] = $action;
}
$request->setPathInfo(implode('/', $parts));
return $request;
}
/**
* Parses and translates the user request.
* @param Request $request the request component
* @return array|boolean the route and the associated parameters. The latter is always empty
* if [[enablePrettyUrl]] is false. False is returned if the current request cannot be successfully parsed.
*/
public function parseRequest($request)
{
return parent::parseRequest($this->translateRequest($request));
}
}
UrlManager 配置:
// ...
'components' => [
// ...
'urlManager' => [
'class' => 'common\components\UrlManager',
// ...
],
],
现在,对于 Yii:$app->language = 'eo';
- /site/test 使用操作测试调用控制器站点。
- /ejo/testo 使用操作测试调用控制器站点。
- /ejo 使用操作索引调用控制器站点。
- /site/testo 使用操作测试调用控制器站点。
对于不同的语言,仅现有路线有效。您可以通过正常方式将参数发送到操作。
是否可以使用当前选择的语言更改控制器名称和操作名称,例如:
如果当前语言是 en 那么 url shuold:
http://localhost/yii2app/site/index
如果当前语言是 da 那么 url 应该:
http://localhost/yii.../websted/indeks
It is what I have tried but it shows 404 not found:
frontend/config/main.php
'urlManager' => [
'baseUrl' => $baseUrl,
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
Yii::t('app','site/index') => Yii::t('app','site/index'),
],
],
在common/messages/da/app.php
return [
'site/index'=>'websted/indeks'
];
在我的layouts/main.php
<a href="<?= Yii::$app->urlManager
->createUrl([Yii::t('app','site/index')])?>">
<?= Yii::t('app','Home') ?>
</a>
您的代码没有 运行 因为当 yii2 加载您的配置时,它没有 Yii
个实例。
对于您的问题,我有 2 个想法。希望有用。
1:使用redirect
示例:
public function actionIndex()
{
if(Yii::$app->language === 'da')
return $this->redirect(['websted/indeks']);
else
return $this->redirect(['site/index']);
}
当用户请求 site/index
时,yii 将根据您的语言重定向到其他 link。当语言为 da
时,浏览器中的地址将更改为 @baseUrl/websted/indeks
。但是,只要您的应用程序中有新语言,您就必须定义和更改代码。
2。将 rule
设为 bootstrap
配置:
'bootstrap' => [
'log',
[
'class' => 'app\components\Bootstrap',
],
],
Bootstrap.php
namespace app\components;
use Yii;
use yii\base\BootstrapInterface;
class Bootstrap implements BootstrapInterface
{
public function bootstrap($app)
{
$app->urlManager->addRules(['site/test' => Yii::t('app','site/test')]);
}
}
语言 1,app.php
return [
'site/test'=>'site/test1',
];
语言 2,app.php
return [
'site/test'=>'site/test2',
];
控制器(示例SiteController
):
public function actionTest1()
{
echo 1;
}
public function actionTest2()
{
echo 2;
}
但问题是:当用户请求 site/test
时,yii 会检查语言和 运行 操作 test1
或 test2
,而您浏览器中的地址只有 @baseUrl/site/test
.
祝你好运,玩得开心!
我已经修改了 Yii 论坛中的这段代码以适用于当前的框架版本。它需要进行测试,因为我很确定那里没有涵盖所有案例。
common\components\UrlManager.php:
<?php
namespace common\components;
use Yii;
use yii\web\Request;
use yii\web\UrlManager as YiiUrlManager;
/**
* UrlManager
* Allows to translate urls dynamically.
*/
class UrlManager extends YiiUrlManager
{
public $enablePrettyUrl = true;
public $showScriptName = false;
public $language;
/**
* Translated controllers names.
* language code => [
* source name => translated name
* ]
* @var array
*/
public $languageControllers = [
'eo' => [
'site' => 'ejo',
'users' => 'uzantoj'
],
];
/**
* Translated actions names.
* language code => [
* source name => translated name
* ]
* @var array
*/
public $languageActions = [
'eo' => [
'contact' => 'kontakton',
'about' => 'pri-ni',
'test' => 'testo'
],
];
/**
* Initializes UrlManager.
*/
public function init()
{
parent::init();
if (empty($this->language)) {
$this->language = Yii::$app->language;
}
}
/**
* Creates translated url.
* @param array $params
* @return string the created URL
*/
public function createUrl($params)
{
$params = (array)$params;
$route = explode('/', trim($params[0], '/'));
if (isset($route[0]) && !empty($this->languageControllers[$this->language][$route[0]])) {
$route[0] = $this->languageControllers[$this->language][$route[0]];
}
if (isset($route[1]) && !empty($this->languageActions[$this->language][$route[1]])) {
$route[1] = $this->languageActions[$this->language][$route[1]];
}
$params[0] = implode('/', $route);
return parent::createUrl($params);
}
/**
* Translates the request back to the source one.
* @param Request $request the request component
* @return Request
*/
public function translateRequest($request)
{
if (empty($this->languageControllers[$this->language])) {
return $request;
}
$url = ltrim($request->getPathInfo(), '/');
$parts = explode('/', $url);
$controller = $parts[0];
$action = isset($parts[1]) ? $parts[1] : null;
foreach ($this->languageControllers[$this->language] as $default => $localized) {
if ($localized == $controller) {
$controller = $default;
break;
}
}
$parts[0] = $controller;
if ($action !== null) {
foreach ($this->languageActions[$this->language] as $default => $localized) {
if ($localized === substr($action, 0, mb_strlen($localized, 'UTF-8'))) {
$action = $default . substr($action, mb_strlen($localized, 'UTF-8'));
break;
}
}
$parts[1] = $action;
}
$request->setPathInfo(implode('/', $parts));
return $request;
}
/**
* Parses and translates the user request.
* @param Request $request the request component
* @return array|boolean the route and the associated parameters. The latter is always empty
* if [[enablePrettyUrl]] is false. False is returned if the current request cannot be successfully parsed.
*/
public function parseRequest($request)
{
return parent::parseRequest($this->translateRequest($request));
}
}
UrlManager 配置:
// ...
'components' => [
// ...
'urlManager' => [
'class' => 'common\components\UrlManager',
// ...
],
],
现在,对于 Yii:$app->language = 'eo';
- /site/test 使用操作测试调用控制器站点。
- /ejo/testo 使用操作测试调用控制器站点。
- /ejo 使用操作索引调用控制器站点。
- /site/testo 使用操作测试调用控制器站点。
对于不同的语言,仅现有路线有效。您可以通过正常方式将参数发送到操作。