在Yii2应用程序中设置全局语言值

时间:2022-11-24 20:20:19

Where can I set language (based on user's cookie) globally? How to make it work in the whole application (controllers,views, etc.) ?

我在哪里可以在全球范围内设置语言(基于用户的cookie)?如何使它在整个应用程序(控制器,视图等)中工作?

In documentation I found \Yii::$app->language = ''; but, where I can write my logic to change the language in right way?

在文档中我找到了\ Yii :: $ app-> language ='';但是,在哪里我可以写出我的逻辑以正确的方式改变语言?

7 个解决方案

#1


13  

You should use

你应该用

\Yii::$app->language = ''; 

inside the controller that is parent to all your controllers. The parent class should be inside the components folder, and if it is not available than create the component with something like

在所有控制器的父控制器内部。父类应该在components文件夹中,如果它不可用,则创建类似的组件

use yii\web\Controller;
class MyController extends Controller
{
    public function init()
    {
        parent::init();
        #add your logic: read the cookie and then set the language
    }
}

After that, you have to be sure that all your controllers extends your newly created MyController instead of the original one.

之后,您必须确保所有控制器都扩展了新创建的MyController而不是原始的。

I hope it helps.

我希望它有所帮助。

#2


17  

You can set your base language in the configuration file. In the basic application it's default location is: /config/web.php, in advanced: application-name/config/main.php and application-name/config/main-local.php.

您可以在配置文件中设置基本语言。在基本应用程序中,它的默认位置是:/config/web.php,在高级:application-name / config / main.php和application-name / config / main-local.php。

$config = [
    'id' => 'basic',
    'language' => 'nl', // Set the language here
    'basePath' => dirname( __DIR__ ),
    'bootstrap' => ['log'],
    ...
];

#3


3  

The accepted answer is a very good one, but just in case you want something "even more global" you can use the bootstrap functionality, or the "on beforeAction" to trigger a function (both via the configuration):

接受的答案非常好,但是如果您想要“更全局”的东西,您可以使用引导功能或“on beforeAction”触发功能(通过配置):

Bootstrap:

$config = [
  ...
  'bootstrap' => ['your\own\component'],
  ...
];

You can then use the init()-function of that component for example.

然后,您可以使用该组件的init() - 函数。

"on beforeaction":

$config = [
   'on beforeAction' => function($event) {
      // set language
   } 
];

#4


0  

Roman, you can achieve your goal using a main configuration file or param. Just make a variable like $sitelang = 'UK_ua'; then you can use it via Yii::$app->params['sitelang']

罗马,您可以使用主配置文件或参数来实现目标。只需创建一个像$ sitelang ='UK_ua'的变量;然后你可以通过Yii :: $ app-> params ['sitelang']使用它

#5


0  

There are many answer to your question, depending on your logic. If you have a static rule:

根据您的逻辑,您的问题有很多答案。如果您有静态规则:

return [
    ...
    'language' => 'it',
    ...
];

See http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html#configuration

If you want implement the ordinary HTTP content negotiation, you have a dedicated component:

如果要实现普通的HTTP内容协商,则需要一个专用组件:

return [
    ...
    'components' => [
        ...
        'contentNegotiator' => [
            'class' => 'yii\filters\ContentNegotiator',
            'languages' => ['en', 'it'],
        ],
        ...
    ],
];

See http://www.yiiframework.com/doc-2.0/guide-structure-filters.html#content-negotiator

If you need a more complex negotiation, you can create a bootstrap component. Here is an example where the language is taken from user preferences for a logged in user or negotiated for guests. Note that you can overload your application with complex operations, like taking the supported languages from a database.

如果需要更复杂的协商,则可以创建引导组件。下面是一个示例,其中语言取自登录用户的用户首选项或为访客协商。请注意,您可以使用复杂的操作重载应用程序,例如从数据库中获取支持的语言。

/**
 * Select a language from user preferences or content negotiation
 */
class LanguageSelector implements BootstrapInterface
{
    public function bootstrap($app)
    {
        if (\Yii::$app->user->isGuest) {
            $supportedLanguages = (new \yii\db\Query())
                ->select('iso639_1')
                ->from('language')
                ->orderBy(['priority' => SORT_ASC])
                ->column();

            $app->language = $app->request->getPreferredLanguage($supportedLanguages);

        } else {
            $app->language = Language::findOne(\Yii::$app->user->identity->language_id)->iso639_1;
        }
    }
}

There's a good reading here about this topic: https://yii2-cookbook.readthedocs.io/i18n-selecting-application-language/

关于这个主题有一个很好的阅读:https://yii2-cookbook.readthedocs.io/i18n-selecting-application-language/

#6


0  

Go to application configuration file frontend/main/config.php or backend/main/config.php

转到应用程序配置文件frontend / main / config.php或backend / main / config.php

$config = ['language' => 'ru-RU']

$ config = ['language'=>'ru-RU']

#7


-1  

I know this is old but, I found this question while I was searching an answer. I also find a nice guide, link below.

我知道这已经过时了,但我在寻找答案时发现了这个问题。我也找到了一个很好的指南,链接如下。

One of the ways to do it to create a component and bootstrap it, like so:

其中一种方法是创建组件并引导它,如下所示:

Create a file in, say, common/components/LanguageSelector.php

在common / components / LanguageSelector.php中创建一个文件

<?php

namespace common\components;

use yii\base\BootstrapInterface;

class LanguageSelector implements \yii\base\BootstrapInterface
{
    public $supportedLanguages = [];

    public function bootstrap($app)
    {
        $preferredLanguage = $app->request->getPreferredLanguage($this->supportedLanguages);
        $app->language = $preferredLanguage;
    }
}

I'm using advanced app template, you can adjust the file location and namespace as needed.

我正在使用高级应用程序模板,您可以根据需要调整文件位置和命名空间。

Then, in your config file, you need to add this component, just like you are adding another component like debug, or log components, like so:

然后,在配置文件中,您需要添加此组件,就像添加其他组件(如debug)或日志组件一样,如下所示:

'components' => [
    'languageSelector' => [
        'class' => 'common\components\LanguageSelector',
        'supportedLanguages' => ['en-US', 'tr-TR'],
    ],
],

Also, you need to add this component to bootstrapped components in your config file:

此外,您需要将此组件添加到配置文件中的引导组件:

'bootstrap' => ['languageSelector', ...]

This approach does not rely on cookies however, it relies on the language of the client browser. You also can find an example on below page in how to achieve preference based language selection. But basically what you need to do is, in your languageSelector component, getting the value from the cookie and change the language accordingly. If there is not a cookie present in the user browser, you can fallback to the browser language.

这种方法不依赖于cookie,但它依赖于客户端浏览器的语言。您还可以在下面的页面中找到有关如何实现基于偏好的语言选择的示例。但基本上你需要做的是,在你的languageSelector组件中,从cookie中获取值并相应地更改语言。如果用户浏览器中没有cookie,您可以回退到浏览器语言。

https://github.com/samdark/yii2-cookbook/blob/master/book/i18n-selecting-application-language.md

#1


13  

You should use

你应该用

\Yii::$app->language = ''; 

inside the controller that is parent to all your controllers. The parent class should be inside the components folder, and if it is not available than create the component with something like

在所有控制器的父控制器内部。父类应该在components文件夹中,如果它不可用,则创建类似的组件

use yii\web\Controller;
class MyController extends Controller
{
    public function init()
    {
        parent::init();
        #add your logic: read the cookie and then set the language
    }
}

After that, you have to be sure that all your controllers extends your newly created MyController instead of the original one.

之后,您必须确保所有控制器都扩展了新创建的MyController而不是原始的。

I hope it helps.

我希望它有所帮助。

#2


17  

You can set your base language in the configuration file. In the basic application it's default location is: /config/web.php, in advanced: application-name/config/main.php and application-name/config/main-local.php.

您可以在配置文件中设置基本语言。在基本应用程序中,它的默认位置是:/config/web.php,在高级:application-name / config / main.php和application-name / config / main-local.php。

$config = [
    'id' => 'basic',
    'language' => 'nl', // Set the language here
    'basePath' => dirname( __DIR__ ),
    'bootstrap' => ['log'],
    ...
];

#3


3  

The accepted answer is a very good one, but just in case you want something "even more global" you can use the bootstrap functionality, or the "on beforeAction" to trigger a function (both via the configuration):

接受的答案非常好,但是如果您想要“更全局”的东西,您可以使用引导功能或“on beforeAction”触发功能(通过配置):

Bootstrap:

$config = [
  ...
  'bootstrap' => ['your\own\component'],
  ...
];

You can then use the init()-function of that component for example.

然后,您可以使用该组件的init() - 函数。

"on beforeaction":

$config = [
   'on beforeAction' => function($event) {
      // set language
   } 
];

#4


0  

Roman, you can achieve your goal using a main configuration file or param. Just make a variable like $sitelang = 'UK_ua'; then you can use it via Yii::$app->params['sitelang']

罗马,您可以使用主配置文件或参数来实现目标。只需创建一个像$ sitelang ='UK_ua'的变量;然后你可以通过Yii :: $ app-> params ['sitelang']使用它

#5


0  

There are many answer to your question, depending on your logic. If you have a static rule:

根据您的逻辑,您的问题有很多答案。如果您有静态规则:

return [
    ...
    'language' => 'it',
    ...
];

See http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html#configuration

If you want implement the ordinary HTTP content negotiation, you have a dedicated component:

如果要实现普通的HTTP内容协商,则需要一个专用组件:

return [
    ...
    'components' => [
        ...
        'contentNegotiator' => [
            'class' => 'yii\filters\ContentNegotiator',
            'languages' => ['en', 'it'],
        ],
        ...
    ],
];

See http://www.yiiframework.com/doc-2.0/guide-structure-filters.html#content-negotiator

If you need a more complex negotiation, you can create a bootstrap component. Here is an example where the language is taken from user preferences for a logged in user or negotiated for guests. Note that you can overload your application with complex operations, like taking the supported languages from a database.

如果需要更复杂的协商,则可以创建引导组件。下面是一个示例,其中语言取自登录用户的用户首选项或为访客协商。请注意,您可以使用复杂的操作重载应用程序,例如从数据库中获取支持的语言。

/**
 * Select a language from user preferences or content negotiation
 */
class LanguageSelector implements BootstrapInterface
{
    public function bootstrap($app)
    {
        if (\Yii::$app->user->isGuest) {
            $supportedLanguages = (new \yii\db\Query())
                ->select('iso639_1')
                ->from('language')
                ->orderBy(['priority' => SORT_ASC])
                ->column();

            $app->language = $app->request->getPreferredLanguage($supportedLanguages);

        } else {
            $app->language = Language::findOne(\Yii::$app->user->identity->language_id)->iso639_1;
        }
    }
}

There's a good reading here about this topic: https://yii2-cookbook.readthedocs.io/i18n-selecting-application-language/

关于这个主题有一个很好的阅读:https://yii2-cookbook.readthedocs.io/i18n-selecting-application-language/

#6


0  

Go to application configuration file frontend/main/config.php or backend/main/config.php

转到应用程序配置文件frontend / main / config.php或backend / main / config.php

$config = ['language' => 'ru-RU']

$ config = ['language'=>'ru-RU']

#7


-1  

I know this is old but, I found this question while I was searching an answer. I also find a nice guide, link below.

我知道这已经过时了,但我在寻找答案时发现了这个问题。我也找到了一个很好的指南,链接如下。

One of the ways to do it to create a component and bootstrap it, like so:

其中一种方法是创建组件并引导它,如下所示:

Create a file in, say, common/components/LanguageSelector.php

在common / components / LanguageSelector.php中创建一个文件

<?php

namespace common\components;

use yii\base\BootstrapInterface;

class LanguageSelector implements \yii\base\BootstrapInterface
{
    public $supportedLanguages = [];

    public function bootstrap($app)
    {
        $preferredLanguage = $app->request->getPreferredLanguage($this->supportedLanguages);
        $app->language = $preferredLanguage;
    }
}

I'm using advanced app template, you can adjust the file location and namespace as needed.

我正在使用高级应用程序模板,您可以根据需要调整文件位置和命名空间。

Then, in your config file, you need to add this component, just like you are adding another component like debug, or log components, like so:

然后,在配置文件中,您需要添加此组件,就像添加其他组件(如debug)或日志组件一样,如下所示:

'components' => [
    'languageSelector' => [
        'class' => 'common\components\LanguageSelector',
        'supportedLanguages' => ['en-US', 'tr-TR'],
    ],
],

Also, you need to add this component to bootstrapped components in your config file:

此外,您需要将此组件添加到配置文件中的引导组件:

'bootstrap' => ['languageSelector', ...]

This approach does not rely on cookies however, it relies on the language of the client browser. You also can find an example on below page in how to achieve preference based language selection. But basically what you need to do is, in your languageSelector component, getting the value from the cookie and change the language accordingly. If there is not a cookie present in the user browser, you can fallback to the browser language.

这种方法不依赖于cookie,但它依赖于客户端浏览器的语言。您还可以在下面的页面中找到有关如何实现基于偏好的语言选择的示例。但基本上你需要做的是,在你的languageSelector组件中,从cookie中获取值并相应地更改语言。如果用户浏览器中没有cookie,您可以回退到浏览器语言。

https://github.com/samdark/yii2-cookbook/blob/master/book/i18n-selecting-application-language.md