在一个多语种应用程序的情况下,人们可能会认为在会话变量中保存首选语言是一种合理的方法,之后,每一个页面被请求时,检查这个会话变量,并在指定的页面显示这语言。本教程显示了Yii的方式来解决此问题。 我们为onBeginRequest事件实现一个事件处理程序,这个事件处理程序在每一个请求的开始时调用,所以这里是一个比较好的地方来检查语言是否提供(post,会话变量或coookie)并设置相应的语言,我们还实现了一个简单的语言选择部件,这可以以一个ajax链接或下拉列表的方式显示语言选项。
也可以使用 来替代。
'sourceLanguage'=>'en', 'language'=>'de',
现在开始实现...
'components/widgets/LanguageSelector.php'
class LanguageSelector extends CWidget { public function run() { $currentLang = Yii::app()->language; $languages = Yii::app()->params->languages; $this->render('languageSelector', array('currentLang' => $currentLang, 'languages'=>$languages)); } }
我在配置文件中设置可用的语言(如下)并且通过Yii::app()->params->languages的方式来使用。
'components/widgets/views/languageSelector.php'
echo CHtml::form(); ?> <div id="language-select"> php if(sizeof($languages) < 4) { $lastElement = end($languages); foreach($languages as $key=>$lang) { if($key != $currentLang) { echo CHtml::ajaxLink($lang,'', array( 'type'=>'post', 'data'=>'_lang='.$key.'&YII_CSRF_TOKEN='.Yii::app()->request->csrfToken, 'success' => 'function(data) {window.location.reload();}' ), array() ); } else echo ''.$lang.''; if($lang != $lastElement) echo ' | '; } } else { echo CHtml::dropDownList('_lang', $currentLang, $languages, array( 'submit' => '', 'csrf'=>true, ) ); } ?> div>php echo CHtml::endForm(); ?>
如果可用的语言少于4种,将会以 '|' 分隔的 ajax 链接显示,当点击的时候ajax将会发送post请求到当前页面,如果成功的话将重新加载页面,注意我在请求中发送了 'YII_CSRF_TOKEN',因为我在配置文件中开启了 cookie 验证了 CSRF(见下)。 如果语言的数量大于4,将生成一个下拉列表。 你也可以只使用一个下拉列表。
'views/layouts/main.php' 请把这个控件放到
<div id="language-selector" style="float:right; margin:5px;"> php $this->widget('application.components.widgets.LanguageSelector'); ?> div>
'config/main.php' 把这几行放到文件中,而不是替换内容
return array( 'sourceLanguage'=>'en', // Associates a behavior-class with the onBeginRequest event. // By placing this within the primary array, it applies to the application as a whole 'behaviors'=>array( 'onBeginRequest' => array( 'class' => 'application.components.behaviors.BeginRequest' ), ), // application components 'components'=>array( 'request'=>array( 'enableCookieValidation'=>true, 'enableCsrfValidation'=>true, ), // ...some other components here... ), // application-level parameters 'params'=>array( 'languages'=>array('tr'=>'Türk?e', 'en'=>'English', 'de'=>'Deutsch'), ), );
'components/behaviors/BeginRequest.php'
class BeginRequest extends CBehavior { // The attachEventHandler() mathod attaches an event handler to an event. // So: onBeginRequest, the handleBeginRequest() method will be called. public function attach($owner) { $owner->attachEventHandler('onBeginRequest', array($this, 'handleBeginRequest')); } public function handleBeginRequest($event) { $app = Yii::app(); $user = $app->user; if (isset($_POST['_lang'])) { $app->language = $_POST['_lang']; $app->user->setState('_lang', $_POST['_lang']); $cookie = new CHttpCookie('_lang', $_POST['_lang']); $cookie->expire = time() + (60*60*24*365); // (1 year) Yii::app()->request->cookies['_lang'] = $cookie; } else if ($app->user->hasState('_lang')) $app->language = $app->user->getState('_lang'); else if(isset(Yii::app()->request->cookies['_lang'])) $app->language = Yii::app()->request->cookies['_lang']->value; } }
这就是所有了
如果不清楚,错误或未完成的请联系我。