yii2 i18n学习
举例说明常见的翻译:Yii::t('app','Login');
追踪源码:BaseYii.php 文件 ,Yii::t($category, $message, $params = [], $language = null) 这个方法实际上是 \yii\i18n\I18N::translate()的一个捷径方法
/**
* 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:
*
* ```php
* $username = 'Alexander';
* echo \Yii::t('app', 'Hello, {username}!', ['username' => $username]);
* ```
*
* Further formatting of message parameters is supported using the [PHP intl extensions](http://www.php.net/manual/en/intro.intl.php)
* message formatter. See [[\yii\i18n\I18N::translate()]] for more details.
*
* @param string $category the message category.
* @param string $message the message to be translated.
* @param array $params the parameters that will be used to replace the corresponding placeholders in the message.
* @param string $language the language code (e.g. `en-US`, `en`). If this is null, the current
* [[\yii\base\Application::language|application language]] will be used.
* @return string the translated message.
*/
public static function t($category, $message, $params = [], $language = null)
{
if (static::$app !== null) {
return static::$app->getI18n()->translate($category, $message, $params, $language ?: static::$app->language);
} else {
$p = [];
foreach ((array) $params as $name => $value) {
$p['{' . $name . '}'] = $value;
} return ($p === []) ? $message : strtr($message, $p);
}
}
查看 \yii\i18n\I18N::translate()方法:
/**
* Translates a message to the specified language.
*
* After translation the message will be formatted using [[MessageFormatter]] if it contains
* ICU message format and `$params` are not empty.
*
* @param string $category the message category.
* @param string $message the message to be translated.
* @param array $params the parameters that will be used to replace the corresponding placeholders in the message.
* @param string $language the language code (e.g. `en-US`, `en`).
* @return string the translated and formatted message.
*/
public function translate($category, $message, $params, $language)
{
// 返回MessageSource the message source for the given category.
$messageSource = $this->getMessageSource($category);
//返回翻译的内容
$translation = $messageSource->translate($category, $message, $language);
//格式话翻译的内容
if ($translation === false) {
return $this->format($message, $params, $messageSource->sourceLanguage);
} else {
return $this->format($translation, $params, $language);
}
}
其中 $messageSource = $this->getMessageSource($category);//根据配置文件内容和 给的参数$category 返回继承MessageSource 相应子类的实例对象, 本例根据配置文件返回PhpMessageSource对象
<?php
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'i18n'=>[
'translations' => [
'app*'=> [
'class' => 'yii\i18n\PhpMessageSource',
'basePath'=>'@common/messages',
'fileMap'=>[
'app'=>'app.php',
],
],
],
],
],
];
$messageSource = $this->getMessageSource($category); 返回继承MessageSource 相应子类的实例对象
/**
* Returns the message source for the given category.
* @param string $category the category name.
* @return MessageSource the message source for the given category.
* @throws InvalidConfigException if there is no message source available for the specified category.
*/
//根据配置文件内容和 给的参数$category 返回继承MessageSource 相应子类的实例对象, 本例根据配置文件返回PhpMessageSource对象
public function getMessageSource($category)
{
if (isset($this->translations[$category])) {
$source = $this->translations[$category];
if ($source instanceof MessageSource) {
return $source;
} else {
return $this->translations[$category] = Yii::createObject($source);
}
} else {
// try wildcard matching
foreach ($this->translations as $pattern => $source) {
if (strpos($pattern, '*') > 0 && strpos($category, rtrim($pattern, '*')) === 0) {
if ($source instanceof MessageSource) {
return $source;
} else {
return $this->translations[$category] = $this->translations[$pattern] = Yii::createObject($source);
}
}
}
// match '*' in the last
if (isset($this->translations['*'])) {
$source = $this->translations['*'];
if ($source instanceof MessageSource) {
return $source;
} else {
return $this->translations[$category] = $this->translations['*'] = Yii::createObject($source);
}
}
} throw new InvalidConfigException("Unable to locate message source for category '$category'.");
}
再根据实例对象的translate方法返回翻译的内容, $translation = $messageSource->translate($category, $message, $language);
MessageSource 类的 translate方法如下:
/**
* Translates a message to the specified language.
*
* Note that unless [[forceTranslation]] is true, if the target language
* is the same as the [[sourceLanguage|source language]], the message
* will NOT be translated.
*
* If a translation is not found, a [[EVENT_MISSING_TRANSLATION|missingTranslation]] event will be triggered.
*
* @param string $category the message category
* @param string $message the message to be translated
* @param string $language the target language
* @return string|boolean the translated message or false if translation wasn't found or isn't required
*/
// 翻译一段信息为指定的语言文件下的内容
public function translate($category, $message, $language)
{
if ($this->forceTranslation || $language !== $this->sourceLanguage) { return $this->translateMessage($category, $message, $language);
} else {
return false;
}
}
$this->translateMessage($category, $message, $language);
/**
* Translates the specified message.
* If the message is not found, a [[EVENT_MISSING_TRANSLATION|missingTranslation]] event will be triggered.
* If there is an event handler, it may provide a [[MissingTranslationEvent::$translatedMessage|fallback translation]].
* If no fallback translation is provided this method will return `false`.
* @param string $category the category that the message belongs to.
* @param string $message the message to be translated.
* @param string $language the target language.
* @return string|boolean the translated message or false if translation wasn't found.
*/
protected function translateMessage($category, $message, $language)
{
$key = $language . '/' . $category;
if (!isset($this->_messages[$key])) {
// $language = 'zh-CN' $category = 'app'
// $this->loadMessages($category, $language) 为合并后的指定类别语言的翻译数组 key => value
$this->_messages[$key] = $this->loadMessages($category, $language);
}
if (isset($this->_messages[$key][$message]) && $this->_messages[$key][$message] !== '') {
return $this->_messages[$key][$message];
} elseif ($this->hasEventHandlers(self::EVENT_MISSING_TRANSLATION)) {
$event = new MissingTranslationEvent([
'category' => $category,
'message' => $message,
'language' => $language,
]);
$this->trigger(self::EVENT_MISSING_TRANSLATION, $event);
if ($event->translatedMessage !== null) {
return $this->_messages[$key][$message] = $event->translatedMessage;
}
} return $this->_messages[$key][$message] = false;
}
根据配置文件生成的 MessageSource子类相应对象的loadMessages方法,生成翻译的文件数组内容,在根据内容查找相应的以$message为键的对应值:
return $this->_messages[$key][$message];
本例根据PhpMessageSource对象的translateMessage方法为例说明:
/**
* Loads the message translation for the specified $language and $category.
* If translation for specific locale code such as `en-US` isn't found it
* tries more generic `en`. When both are present, the `en-US` messages will be merged
* over `en`. See [[loadFallbackMessages]] for details.
* If the $language is less specific than [[sourceLanguage]], the method will try to
* load the messages for [[sourceLanguage]]. For example: [[sourceLanguage]] is `en-GB`,
* $language is `en`. The method will load the messages for `en` and merge them over `en-GB`.
*
* @param string $category the message category
* @param string $language the target language
* @return array the loaded messages. The keys are original messages, and the values are the translated messages.
* @see loadFallbackMessages
* @see sourceLanguage
*/
protected function loadMessages($category, $language)
{
//返回指定类别和语言的文件路径
$messageFile = $this->getMessageFilePath($category, $language);
// 根据文件路径,加载翻译文件,为数组键值对
$messages = $this->loadMessagesFromFile($messageFile); $fallbackLanguage = substr($language, 0, 2);
$fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2); if ($language !== $fallbackLanguage) {
// $language = 'zh-CN' $fallbackLanguage = 'zh' 合并语言zh-CN和zh文件为新的$messages
$messages = $this->loadFallbackMessages($category, $fallbackLanguage, $messages, $messageFile);
} elseif ($language === $fallbackSourceLanguage) {
// $language = 'zh' $fallbackLanguage = 'zh' $this->sourceLanguage = 'en' 合并zh 文件和en 文件,当zh文件翻译key的value信息没有时用 en 文件的相应的value 替代,合并为新的翻译数组内容 $messages
$messages = $this->loadFallbackMessages($category, $this->sourceLanguage, $messages, $messageFile);
} else {
if ($messages === null) {
Yii::error("The message file for category '$category' does not exist: $messageFile", __METHOD__);
}
} return (array) $messages;
}
//返回指定类别和语言的文件路径
$messageFile = $this->getMessageFilePath($category, $language);
/**
* Returns message file path for the specified language and category.
*
* @param string $category the message category
* @param string $language the target language
* @return string path to message file
*/
//返回指定的语言和类别文件路径
protected function getMessageFilePath($category, $language)
{
//语言类别文件路径
$messageFile = Yii::getAlias($this->basePath) . "/$language/";
if (isset($this->fileMap[$category])) {
$messageFile .= $this->fileMap[$category];
} else {
$messageFile .= str_replace('\\', '/', $category) . '.php';
} return $messageFile;
}
// 根据文件路径,加载翻译文件,为数组键值对
$messages = $this->loadMessagesFromFile($messageFile);
/**
* Loads the message translation for the specified language and category or returns null if file doesn't exist.
*
* @param string $messageFile path to message file
* @return array|null array of messages or null if file not found
*/
//加载翻译文件,翻译文件为数组文件
protected function loadMessagesFromFile($messageFile)
{
if (is_file($messageFile)) {
$messages = include($messageFile);
if (!is_array($messages)) {
$messages = [];
} return $messages;
} else {
return null;
}
}
//根据不同的条件,从其他文件中补充语言文件的缺少的key 的值value
$messages = $this->loadFallbackMessages($category, $this->sourceLanguage, $messages, $messageFile);
/**
* The method is normally called by [[loadMessages]] to load the fallback messages for the language.
* Method tries to load the $category messages for the $fallbackLanguage and adds them to the $messages array.
*
* @param string $category the message category
* @param string $fallbackLanguage the target fallback language
* @param array $messages the array of previously loaded translation messages.
* The keys are original messages, and the values are the translated messages.
* @param string $originalMessageFile the path to the file with messages. Used to log an error message
* in case when no translations were found.
* @return array the loaded messages. The keys are original messages, and the values are the translated messages.
* @since 2.0.7
*/
protected function loadFallbackMessages($category, $fallbackLanguage, $messages, $originalMessageFile)
{
// 返回的信息文件路径
$fallbackMessageFile = $this->getMessageFilePath($category, $fallbackLanguage);
//根据文件路径信息,加载文件的内容
$fallbackMessages = $this->loadMessagesFromFile($fallbackMessageFile); if (
$messages === null && $fallbackMessages === null
&& $fallbackLanguage !== $this->sourceLanguage
&& $fallbackLanguage !== substr($this->sourceLanguage, 0, 2)
) {
Yii::error("The message file for category '$category' does not exist: $originalMessageFile "
. "Fallback file does not exist as well: $fallbackMessageFile", __METHOD__);
} elseif (empty($messages)) {
return $fallbackMessages;
} elseif (!empty($fallbackMessages)) {
// 当$message数组key 值为空时,且$fallbackMessages对应的key的翻译内容存在是,把$fallbackMessages的内容翻译数组赋值给 $messages[$key]
foreach ($fallbackMessages as $key => $value) {
if (!empty($value) && empty($messages[$key])) {
$messages[$key] = $fallbackMessages[$key];
}
}
} return (array) $messages;
}
最后返回$messages:
return (array) $messages; 根据提供的参数($message)把$message作为key 查找 $messages 数组中对应的key的值
yii2 i18n学习的更多相关文章
- 国际化(i18n)学习
一 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 国际化(internationalization)又称 ...
- yii2框架学习笔记
1.去掉yii2模版默认的头部和脚部的两种方法: (1) 第一种 $this->layout = false; $this->render('index'); (2) 第二种(partia ...
- Yii2.0学习笔记:创建登录表单
第一步:在model层创建一个EntryForm.php文件 复制以下代码,注意model的文件.方法.类的命名规范(大小写) <?php namespace app\models; use Y ...
- Yii2.0学习笔记:第一个页面Saying Hello
Controller目录下创建TestController.php 复制下面代码,yii跟tp一样,全程命名空间 <?php namespace app\controllers; use yii ...
- Yii2 基础学习
<?php //url创建 echo Url::to(''); // same controller, different action // /index.php?r=management/d ...
- YII2.O学习三 前后台用户数据表分离
之前我们完成了Advanced 模板安装,也完成了安装adminlte 后台模板,这一步是针对前端和后台用户使用不同的数据库表来管理,做到前后台用户分离的效果: 复制一张user数据表并重命名为adm ...
- YII2.0学习二 安装adminlte 后台模板
控制台切换到安装目录wwwroot/shanghai/ 修改一下composer镜像地址:composer 使用中国镜像 运行 composer require dmstr/yii2-adminlte ...
- YII2.0学习一 Advanced 模板安装
下载github上的完事安装包(本机环境使用Composer安装非常慢) https://github.com/yiisoft/yii2-app-advanced 解压到文件目录 wwwroot/sh ...
- Yii2.0学习--目录结构
目录结构: 创建一个控制器: <?php /** * Created by Haima. * Author:Haima * QQ:228654416 * Date: 2018/8/23 * Ti ...
随机推荐
- Qt:使用自定义的字体
Qt:使用自定义的字体 1. 下载字体文件 2. 加载字体文件 3. 使用字体 QFontDatabase::addApplicationFont("XENOTRON.TTF" ...
- CVE爬虫抓取漏洞URL
String url1="http://www.cnnvd.org.cn/vulnerability/index/vulcode2/tomcat/vulcode/tomcat/cnnvdid ...
- VS2012 Build相关
最近写了一个小程序,用到了一些关于build方面的内容,google后,记录一下 1. VS工程下的bin和obj文件夹,bin文件夹下的debug和release文件夹,以及其中的文件 大家可以参考 ...
- C语言一维数组中的数据随机排列
#include <stdio.h>#include <stdlib.h> void randomlize(int *a, int n){ int i = 0,j ...
- pylinter could not automatically determined the path to `lint.py`
先关闭Sublime Text 1) 到官网先下载pylinter,http://www.logilab.org/project/pylint,然后解压缩,拷贝到C盘,目录为C:\pylint-1.0 ...
- IPC:Sockets
Please refer to http://www.cs.cf.ac.uk/Dave/C/node28.html.
- bzoj3211,bzoj3038
线段树的裸题: 但是操作很奇怪,开方是不能lazy tag的 看来只能暴力修改了 但注意,开放开到1的时候就不用开,立一个flag就可以了 这可以大大的优化: 其实我是来复习线段树的 ..] of i ...
- 【转】Android中visibility属性VISIBLE、INVISIBLE、GONE的区别
原文网址:http://blog.csdn.net/chindroid/article/details/8000713 在Android开发中,大部分控件都有visibility这个属性,其属性有3个 ...
- Entity Framework 增删改查和事务操作
1.增加对象 DbEntity db = new DbEntity(); //创建对象实体,注意,这里需要对所有属性进行赋值(除了自动增长主键外),如果不赋值,则会数据库中会被设置为NULL(注意是否 ...
- Kettle定时执行(ETL工具)【转】
1,Kettle跨平台使用. 例如:在AIX下(AIX是IBM商用UNIX操作系统,此处在LINUX/UNIX同样适用),运行Kettle的相关步骤如下: 1)进入到Kettle部署的路径 ...