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 адрес с друг езиков код.

Последният заявен език също се запазва в потребителската сесия и в бисквитка. Така че, ако потребителят се опита да влезе в сайта ви без езиков код в 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' => ''
    ],
]

към (добавете правило за език)

'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

тъй като не е нов ангажимент за този пакет, използвайте това разклонение на Мохамед Амер

или директно използвайте този клас и копирайте го във вашата директория с компоненти, след което направете правила за url като това:

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

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