yii2 создает переведенные URL-адреса

Мне нужно создать удобные для пользователя URL-адреса, которые переведены, но указывают на тот же контроллер, что и другие для языка.

Пример:

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

Я пытался использовать маршруты, но не смог найти способ вызова контроллера в зависимости от переведенного URL-адреса.

Любые намеки, где я должен начать?


person Swissdude    schedule 03.06.2015    source источник


Ответы (5)


Это нелегко сделать со встроенной функциональностью, но у кого-то была такая же потребность, и он написал пакет специально для этого: yii2-localeurls. Я думаю, что это может быть то, что вы ищете:

С этим расширением вы можете использовать URL-адреса, содержащие код языка, например:

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

Вы также можете настроить дружественные имена, если хотите:

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

Код языка автоматически добавляется при создании URL-адреса и считывается при анализе URL-адреса. Для удобства пользователей язык автоматически определяется в настройках браузера, если в URL-адресе не используется язык. Однако пользователь по-прежнему может получить доступ к другим языкам, просто вызвав URL-адрес с кодом другого языка.

Последний запрошенный язык также сохраняется в сеансе пользователя и в файле cookie. Таким образом, если пользователь попытается получить доступ к вашему сайту без кода языка в URL-адресе, он будет перенаправлен на язык, который использовал при последнем посещении.

person Blizz    schedule 03.06.2015
comment
спасибо - но проблема была не в этом, как вы можете видеть из моего собственного ответа. Часть языкового кода было довольно легко реализовать... :) - person Swissdude; 03.06.2015
comment
Точно, не одно и то же. В любом случае, я оставлю ответ, если кто-то действительно ищет только языковую часть. - person Blizz; 03.06.2015

Это мое рабочее решение с использованием https://github.com/codemix/yii2-localeurls кроме того и расширенный шаблон yii2:

Создать 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);
    }
}

И затем на frontend/config/main.php:

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

Итак, /en/myCar, /de/meinAuto и /fr/monVoiture будут использовать правило myCar/index.

person nacesprin    schedule 24.11.2016

Вы можете легко сделать это вручную в Yii2 без каких-либо расширений:

1) Внутри config/web.php изменить правило (например)

из

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

to (добавить правило для языка)

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

сделайте то же самое для других правил, если они у вас есть (например)

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

2) Представим, что у нас есть 3 языка: ru, en, kz. И все контроллеры расширяют наш BehaviorsController.php< /strong> (пример, class MainController extends BehaviorsController)

Внутри BehaviorsController.php создайте функцию beforeAction()

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) Внутри config/params.php добавьте ключ langs в массив

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

4) Вот и все. Теперь мы можем проверить путь, используя параметр языка:

example.com/ru

or

example.com/en

person Nikolay Yenbakhtov    schedule 19.09.2017
comment
Хороший ответ, но лучше использовать yii2-localeurls, потому что у него много функций под капотом, и вам не нужно снова реализовывать существующие функции... - person Akmal; 28.10.2019

Хорошо, оказывается, с правилами все довольно просто (помогли пробы и ошибки):

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

... и так далее...

И просто, чтобы прокомментировать ответ ниже: код языка не был проблемой, я решил это некоторое время назад... проблема заключалась в том, что мне нужна часть контроллера на языке пользователя

person Swissdude    schedule 03.06.2015
comment
Если у вас много таких URL-адресов, вы можете захотеть вернуться к базе данных или около того с помощью своего собственного правила URL-адреса, в противном случае это может стать очень большим списком... - person Blizz; 03.06.2015
comment
действительно, но в моем случае это примерно 3 или 4 URL-адреса, это должно быть выполнимо :) - person Swissdude; 03.06.2015
comment
Тогда вы сами придумали лучшее решение, я думаю :) - person Blizz; 03.06.2015

Всем, кто пришел к этому вопросу, см. этот пакет: Yii2 TranslatableUrlRule

из-за не новой фиксации для этого пакета используйте эту вилку Mohamed Amer

или напрямую используйте этот класс и скопируйте его в каталог компонентов, затем выполните следующие правила URL:

В расширенном проекте я использовал его в каталоге common/components.

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