Is it possible to change controller name and action name with current selected language like:
If current language is en then url shuold:
http://localhost/yii2app/site/index
and if current language is da then url should:
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'),
],
],
in common/messages/da/app.php
return [
'site/index'=>'websted/indeks'
];
In my layouts/main.php
<a href="<?= Yii::$app->urlManager
->createUrl([Yii::t('app','site/index')])?>">
<?= Yii::t('app','Home') ?>
</a>
I have modified this code from the Yii forum to work with the current framework version. It needs to be tested because I'm pretty sure not every case is covered there.
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 configuration:
// ...
'components' => [
// ...
'urlManager' => [
'class' => 'common\components\UrlManager',
// ...
],
],
Now, for Yii:$app->language = 'eo';
For different languages only existing routes work. You can send parameters to action in the normal way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With