【问题标题】:yii2 create translated URLsyii2 创建翻译后的 URL
【发布时间】:2019-11-04 18:33:46
【问题描述】:

我需要创建用户友好的 URL,这些 URL 经过翻译,但指向与其他语言相同的控制器。

例子:

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

我尝试使用路由,但找不到根据翻译后的 URL 调用控制器的方法。

任何提示我应该从哪里开始?

【问题讨论】:

    标签: routes translation yii2


    【解决方案1】:

    使用内置功能不容易做到这一点,但有人有同样的需求并专门为此编写了一个包:yii2-localeurls。我认为这可能是您正在寻找的:

    使用此扩展程序,您可以使用包含以下语言代码的 URL:

    /zh/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 中没有语言代码的情况下访问您的网站,他将被重定向到他上次访问时使用的语言。

    【讨论】:

    • 谢谢 - 但这不是问题,正如您从我自己的回答中看到的那样。语言代码部分很容易实现... :)
    • 对,确实不是一回事。无论如何,如果有人真的单独寻找语言部分,我会留下答案。
    【解决方案2】:

    这是我的工作解决方案,另外使用 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 规则

    【讨论】:

      【解决方案3】:

      您可以在 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(例如,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

      example.com/en

      【讨论】:

      • 不错的答案,但最好使用 yii2-localeurls,因为它有很多功能,您不需要再次实现现有功能...
      【解决方案4】:

      好吧,事实证明,规则非常简单(一些尝试和错误有所帮助):

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

      ...等等...

      只是评论下面的答案:语言代码不是问题,我前段时间解决了这个问题......问题是,我需要用户语言的控制器部分

      【讨论】:

      • 如果您有很多这样的 url,您可能希望通过自己的 URL 规则回退到数据库中,否则可能会变成一个非常大的列表...
      • 确实如此,但就我而言,它只是大约 3 或 4 个 URL,这应该是可行的 :)
      • 那么我猜你自己想出了最好的解决方案:)
      【解决方案5】:

      对于任何提出这个问题的人, 看到这个包:Yii2 TranslatableUrlRule

      因为这个包不是新的提交,所以使用Mohamed Amer这个fork

      或直接使用this class 并将其复制到您的组件目录,然后执行这样的 url 规则:

      在高级项目中,我在 common/components 目录中使用它。

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

      【讨论】:

        猜你喜欢
        • 2016-07-27
        • 1970-01-01
        • 2014-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多