【问题标题】:What is the best approach to implement multi language app using angular and yii2 [closed]使用 angular 和 yii2 实现多语言应用程序的最佳方法是什么 [关闭]
【发布时间】:2021-03-10 09:56:20
【问题描述】:

我在后端使用 yii2 restful api,前端使用 angular。

我想问一下实现多语言功能的最佳方法,该功能可以在同一个地方(数据库表、文件)管理前端和后端。

【问题讨论】:

    标签: angular yii2 yii2-advanced-app angular11 yii2-api


    【解决方案1】:

    理论和指南:

    1. 要在 Yii2 应用程序中实现|启用多语言功能,您应该使用i18n 组件https://www.yiiframework.com/doc/guide/2.0/en/tutorial-i18n

    2. 接下来是检测frontend|backend|api 请求|需要|选择哪种语言。这可以通过多种方式完成:标头、cookie、会话、获取、发布甚至通过主机名。

    3. 在处理请求之前,您需要按某种优先级检测所选语言,语言配置存储在哪里并将其设置为应用程序。

    代码:

    app/common/config/main.php

    return [
    // ...
    'language' => 'en', // base language
    // ...
    'components' => [
    //...
        'i18n' => [
            'translations' => [
                '*' => [
                    'class' => 'yii\i18n\PhpMessageSource',
                    'basePath' => '@common/messages',
                    'sourceLanguage' => 'en',
                ],
            ],
        ],    
    // ...
    ],
    // ...
    
    // handle request and detect language    
    'as beforeRequest' => [
        'class' => app\common\behaviours\LanguageHandler::class,
    ],
    

    app/common/behaviours/LanguageHandler.php

    namespace common\behaviours;
    
    use common\models\User;
    use Yii;
    use yii\base\Behavior;
    use yii\base\Event;
    use yii\helpers\Url;
    use yii\web\Application;
    use yii\web\Cookie;
    
    /**
     * Class LanguageHandler
     * @package common\behaviours
     */
    class LanguageHandler extends Behavior
    {
        const LANG_KEY = 'language';
        public $domainOnly = false;
    
        /**
         * @return array
         */
        public function events()
        {
            return [
                Application::EVENT_BEFORE_REQUEST => 'handleBeginRequest',
            ];
        }
    
        /**
         * Handle app selected language
         *
         * Priority of detecting language
         * 1) Detect from host name
         * 2) Detect from post
         * 3) Detect from headers
         * 4) Detect from cookies
         * 5) Detect from user config
         * 6) Use default app language
         *
         * @param Event $event
         */
        public function handleBeginRequest(Event $event)
        {
            $hostName = $request->getHostName();
            $request = Yii::$app->getRequest();
            $language = $request->post(self::LANG_KEY, null);
            $query = $request->getQueryParams();
            $cookies = $request->getCookies();
            $headers = $request->getHeaders();
    
            /**
             * Try first by domain and hostname
             */
            if ($this->domainOnly) {
                /**
                 * Try first by domain and hostname
                 */
                if (substr($hostName, -3) == '.ru') {
                    $language = 'ru';
                } else {
                    $language = 'en';
                }
            } else {
                if (substr($hostName, -3) == '.ru') {
                    $language = 'ru';
                }
            }
    
            /**
             * Use detected language or try to get language from query params
             */
            $language = $language ?? ($query[self::LANG_KEY] ?? null);
    
            /**
             *  Use detected language or try to get language from request headers
             */
            $language = $language ?? (
                $headers->has(self::LANG_KEY)
                    ? (
                        array_key_exists($headers->get(self::LANG_KEY), Yii::$app->params['languages'])
                            ? $headers->get(self::LANG_KEY)
                            : null
                    )
                    : null
                );
    
            /**
             *  Use detected language or try to get language from cookies headers
             */
            $language = $language ?? (
                $cookies->has(self::LANG_KEY)
                    ? (
                        array_key_exists($cookies->getValue(self::LANG_KEY), Yii::$app->params['languages'])
                            ? $cookies->getValue(self::LANG_KEY)
                            : null
                    )
                    : null
                );
    
            /**
             *  Use detected language or try to get language from user profile
             */
            if (empty($language) && !Yii::$app->user->isGuest) {
                /** @var User $user */
                $user = Yii::$app->user->identity;
                if ($user instanceof User && isset($user->language) && !empty($user->language)) {
                    $language = $user->language;
                }
            }
    
            /**
             * If no language use default
             */
            $language = $language ?? Yii::$app->language;
    
            // Add a cookie for next requests
            $languageCookie = new Cookie([
                'name' => self::LANG_KEY,
                'value' => $language,
                'expire' => time() + 86400 * 365,
            ]);
            Yii::$app->getResponse()->getCookies()->add($languageCookie);
    
            // store selected language to application 
            Yii::$app->language = $language;
        }
    }
    

    现在您可以使用它来实现您的目标,也可以建立您检测语言的优先级。

    您可以从Angular 为请求设置language 标头。

    const headers = {
        'Accept': '*/*',
        'Content-Type': 'multipart/form-data;',
        'X-Requested-With': 'XMLHttpRequest',
        'Access-Control-Allow-Credentials': 'true',
        'Access-Control-Allow-Origin': '*',
        'language': 'en'
    }
    

    【讨论】:

      猜你喜欢
      • 2019-06-14
      • 2011-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-10
      • 2012-06-30
      • 2010-10-01
      • 1970-01-01
      相关资源
      最近更新 更多