yii2 create translated URLs

旧街凉风 提交于 2020-01-04 15:26:47

问题


I need to create user-friendly URLs which are translated, yet point to the same controller as the others for a language.

Example:

/en/myCar/100 -> /de/meinAuto/100 -> /fr/monVoiture/100

I tried using routes but couldn't find a way to call the controller depending on a translated URL.

Any hints where I should start?


回答1:


It can't be done easily with built in functionality, but someone had the same need and wrote a package specifically for this: yii2-localeurls. I think that might be what you are looking for:

With this extension you can use URLs that contain a language code like:

/en/some/page
/de/some/page
http://www.example.com/en/some/page
http://www.example.com/de/some/page

You can also configure friendly names if you want:

http://www.example.com/english/some/page
http://www.example.com/deutsch/some/page

The language code is automatically added whenever you create a URL, and read back when a URL is parsed. For best user experience the language is autodetected from the browser settings, if no language is used in the URL. The user can still access other languages, though, simply by calling a URL with another language code.

The last requested language is also persisted in the user session and in a cookie. So if the user tries to access your site without a language code in the URL, he'll get redirected to the language he had used on his last visit.




回答2:


This is my working solution, by using the https://github.com/codemix/yii2-localeurls in addition and yii2 advanced template:

Create frontend/components/i18nUrlRules.php

namespace frontend\components;
use Yii;
use yii\base\BootstrapInterface;
class i18nUrlRules implements BootstrapInterface
{
    public function bootstrap($app)
    {
        //Place here the translated UrlRules
        $i18nRules=[
            'myCar/index' => [
                'de' => 'meinAuto',
                'fr' => 'monVoiture',
                'en' => 'myCar',
            ],
            '...' => [
                ...
            ],
        ];
        $reqLang=explode("/",$_SERVER['REQUEST_URI'])[1];
        $languages = ['en','de','fr'];
        $reqLang=in_array($reqLang,$languages)?$reqLang:\Yii::$app->language; //If not in array, use the default language
        \Yii::$app->getUrlManager()->addRules(
            [ 
                $i18nRules['myCar/index'][$reqLang] =>'myCar/index',
                ...
            ],
        false);
    }
}

And then on frontend/config/main.php:

'bootstrap' => [
        'log',
        'frontend\components\i18nUrlRules',
    ],

So, /en/myCar, /de/meinAuto and /fr/monVoiture will use myCar/index rule




回答3:


You can do it easy manually in Yii2 without any extensions:

1) Inside config/web.php change you rule (for example)

from

'rules' =>[
    [
        'pattern' => '',
        'route' => 'main/index',
        'suffix' => ''
    ],
]

to (add rule for language)

'rules' =>[
    [
        'pattern' => '',
        'route' => 'main/index',
        'suffix' => ''
    ],
    '<language:\w{2}>'=>'main/index',
]

do the same for other rules if you have (for example)

[
    'pattern' => '<controller>/<action>/<id:\w+>',
    'route' => '<controller>/<action>',
    'suffix' => ''
],
[
    'pattern' => '<language:\w{2}>/<controller>/<action>/<id:\w+>',
    'route' => '<controller>/<action>',
    'suffix' => ''
],

2) Imagine that we have 3 landuages: ru, en, kz. And all controllers extends our BehaviorsController.php (example, class MainController extends BehaviorsController)

Inside BehaviorsController.php create beforeAction() function

public function beforeAction($action)
{       
    $language = Yii::$app->getRequest()->getQueryParam('language');
    if($language){
        if(in_array($language,Yii::$app->params['langs'])) Yii::$app->session->set('lang',$language);
        Yii::$app->language = $language;
    }
    return parent::beforeAction($action);
}

3) Inside config/params.php add langs key to array

return [
    ... // some params
    'langs' => ['RU' => 'ru','KZ' => 'kz','EN' => 'en'],    //allowed languages
];

4) That's it. Now we can check the path using language param:

example.com/ru

or

example.com/en




回答4:


Ok, turns out, it's pretty simple with rules (some trial and error helped):

'<language:(de)>/meinAuto' => 'myCar/index',
'<language:(fr)>/monVoiture' => 'myCar/index'

... and so on...

And just to comment the answer below: the language-code wasn't the problem, I had solved this a while ago... the problem was, that I needed the controller-part in the user's language




回答5:


For anyone who came to this question, see this package: Yii2 TranslatableUrlRule

because of not new commit for this package, use this fork of Mohamed Amer

or directly use this class and copy it to your components directory then do url rules like this:

In advanced project, I used it in common/components directory.

'rules' => [
            [
                'class' => 'common\components\TranslatableUrlRule',
                'patterns' => [
                    'ar' => 'مرحبا',
                    'en' => 'hi',
                    'en' => 'Hola',
                ],
                'route' => '/main/hi',
            ],


来源:https://stackoverflow.com/questions/30620404/yii2-create-translated-urls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!