Home  >  Article  >  php教程  >  Yii2 framework study notes (3) -- Language and internationalization

Yii2 framework study notes (3) -- Language and internationalization

黄舟
黄舟Original
2016-12-30 09:44:131881browse

The internationalization function is generally rarely used, but for learning, it is still necessary to get in touch with it.

The most commonly used method for internationalization is \Yii::t. The official document is as follows

t() public static method
Translates a message to the specified language.
This is a shortcut method of yii\i18n\I18N::translate().
The translation will be conducted according to the message category and the target language will be used.
You can add parameters to a translation message that will be substituted with the corresponding value after translation. 
The format for this is to use curly brackets around the parameter name as you can see in the
following example:
[code]$username = 'Alexander';
echo \Yii::t('app', 'Hello, {username}!', ['username' => $username]);
Further formatting of message parameters is supported using the PHPintl extensions message formatter. See yii\i18n\I18N::translate() formore details.
public static stringt ($category, $message, $params = [],$language = null )    
$category    string    The message category.    
$message    string    The message to be translated.    
$params    array    The parameters that will be used to replace the corresponding placeholders in the message.    
$language    string    The language code (e.g.en-US,en).If this is null, the current application language will be used.    
return
string    The translated message.

There are 4 parameters, but the first two are commonly used.

The first one is the group, and the definition of the group is placed under config/main-local.php.

Yii2 uses English (en-US) by default, and now adds Chinese support (zh-CN)

Add the following block under component

'components' => [
        ...
    	'i18n' => [
    		'translations' => [
    			'common' => [
    				'class' => 'yii\i18n\PhpMessageSource',
    				'basePath' => '@common/messages',
    				'fileMap' => [
    					'common' => 'common.php',
    				],
    			],
    		],	
    	],
        ...
    ],

This code definition A group named common is created. The default class yii\i18n\PhpMessageSource is used to parse the translation file. The translation file is placed under common/messages and the translation file is common.php.

According to the configuration, establish the following directory structure

Yii2 framework study notes (3) -- Language and internationalization

The translation files are organized in an array, and the content is as follows

<?php  
return [  
    &#39;Signup&#39; => &#39;注册&#39;,  
    &#39;Login&#39; => &#39;登陆&#39;,  
    &#39;Logout&#39; => &#39;登出&#39;,  
    &#39;Home&#39; => &#39;首页&#39;,  
    &#39;Contact&#39; => &#39;反馈&#39;,  
    &#39;About&#39; => &#39;关于&#39;,  
];

Then we Do the translation in the layouts file and modify it in /views/layouts/main.php as follows:

$menuItems = [  
        //[&#39;label&#39; => &#39;Home&#39;, &#39;url&#39; => [&#39;/site/index&#39;]],  
        //[&#39;label&#39; => &#39;About&#39;, &#39;url&#39; => [&#39;/site/about&#39;]],  
        //[&#39;label&#39; => &#39;Contact&#39;, &#39;url&#39; => [&#39;/site/contact&#39;]],  
        [&#39;label&#39; => \Yii::t(&#39;common&#39;, &#39;Home&#39;), &#39;url&#39; => [&#39;/site/index&#39;]],  
        [&#39;label&#39; => \Yii::t(&#39;common&#39;, &#39;About&#39;), &#39;url&#39; => [&#39;/site/about&#39;]],  
        [&#39;label&#39; => \Yii::t(&#39;common&#39;, &#39;Contact&#39;), &#39;url&#39; => [&#39;/site/contact&#39;]],  
    ];

Open the page and see if it takes effect.

Unfortunately, it does not take effect. . . . .

Yii2 framework study notes (3) -- Language and internationalization

The reason is that the root language of the website is still en-US and needs to be configured as zh-CN.

In common/config/main-local.php, add the following configuration:

<?php  
return [  
   &#39;language&#39; => &#39;zh-CN&#39;,  
   ...  
];

Check again whether it takes effect.

Yii2 framework study notes (3) -- Language and internationalization

You can see that the translation has taken effect.

But the main reason for using the Yii::t method is to achieve multi-language. If you only display one language, it is better to do hardcode (the yii2 framework actually does the hardcode language display)

yii2 does not provide a ready-made control for switching languages, so we need to develop one ourselves.

The implementation refers to http://www.yiiframework.com/wiki/294/seo-conform-multilingual-urls-language-selector-widget-i18n/, and has been moderately simplified without doing SEO aspects. consideration.

The main idea of ​​implementation is to save the language selected by the user in a cookie, and set the language to the value in the cookie before each user visits the page. Why do you need to set the language each time? The reasons are as follows

Note: If we don't set Yii::app()->language explicitly for each request, it will be equal to its default value set in the confg file. If it is not set in the config file, it will be equal to the value Yii::app()->sourceLanguage, which defaults to 'en_us'.

The general meaning is that if not every time If the value is set, the system will use the default language, which is usually English.

1. Prepare materials, both sides of the flag, put them under frontend/web/image/ and name them en.png and zh.png.

Yii2 framework study notes (3) -- Language and internationalization

2. Configure the available languages ​​in /common/config/main-local.php for us to call in the control

<?php  
return [  
    &#39;language&#39; => &#39;zh-CN&#39;,  
  
    &#39;components&#39; => [  
        ...  
    ],  
    &#39;params&#39; => [  
        &#39;availableLanguages&#39; => [  
            &#39;zh-CN&#39; => [&#39;img&#39; => &#39;image/zh.png&#39;, &#39;desc&#39; => &#39;中文&#39;],  
            &#39;en-US&#39; => [&#39;img&#39; => &#39;image/en.png&#39;, &#39;desc&#39; => &#39;English&#39;],  
        ],  
    ],  
    ...  
];

3. In Create a new php file under /common/widgets/ and name it LanguageSelector.php. The content is as follows:

<?php

namespace common\widgets;

use Yii;
use yii\helpers\Html;
use yii\helpers\Url;

class LanguageSelector
{
	public static function getMenu()
	{
		$lang = Yii::$app->language;
		$avLang = Yii::$app->params[&#39;availableLanguages&#39;];
		$isMatch = false;
		foreach ($avLang as $key => $value) {
			if($key == $lang) {
				$tag = LanguageSelector::buildImgTag($value[&#39;img&#39;], $value[&#39;desc&#39;]);
				$isMatch = true;
			}
		}
		if(!$isMatch) {
			$tag = LanguageSelector::buildImgTag($avLang[0][&#39;img&#39;], $avLang[0][&#39;desc&#39;]);
		}
		$return = [
			&#39;label&#39; => $tag, 
			&#39;items&#39; => LanguageSelector::buildMenuItems($avLang),
		];
		
		return $return;
	}	
	
	private static function buildImgTag($src, $desc)
	{
		return &#39;<img src="&#39; . $src . &#39;" alt="&#39; . $desc . &#39;">&#39;;
	}
	
	private static function buildMenuItems($langs)
	{
		foreach ($langs as $key => $value) {
			$link = Html::a(LanguageSelector::buildImgTag($value[&#39;img&#39;], $value[&#39;desc&#39;]) . &#39; &#39; . $value[&#39;desc&#39;], Url::home(), [
					&#39;title&#39; => LanguageSelector::buildImgTag($value[&#39;img&#39;], $value[&#39;desc&#39;]) . &#39; &#39; . $value[&#39;desc&#39;],
					&#39;onclick&#39;=>"
					     $.ajax({
					    type     :&#39;POST&#39;,
					    cache    : false,
					    url  : &#39;" . Url::toRoute("ajax/lang") . "&#39;,
						data: { _lang : &#39;" . $key . "&#39; },
					    success  : function(response) {
					        window.location.reload();
					    }
					    });return false;",
			]);
			$menuItems[] = &#39;<li>&#39; . $link . &#39;</li>&#39;;
		}
		return $menuItems;
	}
}

The main thing to do is:

Read the configuration items in main-local.php , forming an array.
Rendering menu.
Bind events to the buttons in the menu. When clicked, an ajax request is triggered. After ajax returns successfully, the page is refreshed.

4. Add a controller that handles ajax. Create a new AjaxController.php under frontend/controllers and add the following code:

<?php

namespace frontend\controllers;

use Yii;
use yii\web\Controller;
use common\components\SelectLanguageBehavior;
use yii\web\cookie;

class AjaxController extends Controller {
	public $layout = false;
	
	public function actionLang() {
		if (isset($_POST[&#39;_lang&#39;]))
		{
			$lang = SelectLanguageBehavior::getSelectedLanguage($_POST[&#39;_lang&#39;]);
			Yii::$app->language = $lang;
			$cookie = new cookie([
					&#39;name&#39; => &#39;_lang&#39;,
					&#39;value&#39; => $lang,
			] );
			$cookie->expire = time() + (60*60*24*365); // (1 year)
			Yii::$app->response->cookies->add($cookie);
		}
		return "success";
	}
	
}

The important thing is to set $layouts to false to prevent ajax from returning to render unnecessary things.

5. Add an action (Behaviors) to modify the language every time the user visits the page.
Under common/components (if there is no such directory, create a new directory), create a new SelectLanguageBehavior.php with the following content

<?php
namespace common\components;

use yii\base\Application;
use yii\base\Behavior;
use yii\web\cookie;
use Yii;
class SelectLanguageBehavior extends Behavior
{
	public function events()
	{
		return [
				Application::EVENT_BEFORE_REQUEST => &#39;beforeRequest&#39;,
		];
	}
	
	public function beforeRequest($event) {
		$app = Yii::$app;
	
		$lang = SelectLanguageBehavior::getSelectedLanguage(Yii::$app->request->cookies->getValue(&#39;_lang&#39;));
		$app->language = $lang;
	}
	
	public static function getSelectedLanguage($val) {
		$langs = Yii::$app->params[&#39;availableLanguages&#39;];
		foreach ($langs as $key=>$value) {
			if($val == $key) {
				return $val;
			}
		}
		return key($langs);
	}
}

6. Bind the action to the system.
Add the as beginRequest item in common/config/main-local.php

<?php  
return [  
    &#39;language&#39; => &#39;zh-CN&#39;,  
  
    &#39;components&#39; => [  
        ...  
    ],  
    ...  
    &#39;as beginRequest&#39; => [  
            &#39;class&#39; => &#39;common\components\SelectLanguageBehavior&#39;,  
    ],  
];

7. Add the control to the page.
In frontend/views/layouts/main.php, add code to display our control. Because the control contains html code, we must prevent it from escaping

...
    if (Yii::$app->user->isGuest) {
        $menuItems[] = [&#39;label&#39; => Yii::t(&#39;common&#39;, &#39;Signup&#39;), &#39;url&#39; => [&#39;/site/signup&#39;]];
        $menuItems[] = [&#39;label&#39; => Yii::t(&#39;common&#39;, &#39;Login&#39;), &#39;url&#39; => [&#39;/site/login&#39;]];
    } else {
        $menuItems[] = [
            &#39;label&#39; => Yii::t(&#39;common&#39;, &#39;Logout&#39;) . &#39; (&#39; . Yii::$app->user->identity->username . &#39;)&#39;,
            &#39;url&#39; => [&#39;/site/logout&#39;],
            &#39;linkOptions&#39; => [&#39;data-method&#39; => &#39;post&#39;]
        ];
    }
	
	// add this line
        $menuItems[] = \common\widgets\LanguageSelector::getMenu();
	
	echo Nav::widget([
        &#39;options&#39; => [
        	&#39;class&#39; => &#39;navbar-nav navbar-right&#39;,
        	],
        &#39;items&#39; => $menuItems,
        // add this line
    	&#39;encodeLabels&#39; => false,
    ]);
	...

8. Open the page to view the effect

Yii2 framework study notes (3) -- Language and internationalization

The above are Yii2 framework study notes (3) - language and internationalization content. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn