Yii i18n国际化,消息翻译

实现国际化有两种方式,基于文件实现和基于数据库实现。基于文件实现的方式很简单,网上有很多,请自行查询使用。这里主要说一下基于数据库实现的方式。

前提
待翻译的消息使用Yii::t()方法显示,方法参数,第一个是模式,比如常用的app,符合这种模式的消息,都会被初始化到表中,第二个是要显示的消息内容(这里的模式app在source_message表中对应category字段)。

数据库实现是基于DbMessageSource类实现的。
首先需要两张表:source_message表和message表,前者是存储要被翻译的语言,后者是存储被翻译后的语言,实现映射。

一、生成source_message 和 message表

#source_message表
CREATE TABLE source_message (
    id INTEGER PRIMARY KEY AUTO_INCREMENT,
    category VARCHAR(32),
    message TEXT
);

#message表
CREATE TABLE message (
    id INTEGER,
    language VARCHAR(16),
    translation TEXT,
    PRIMARY KEY (id, language),
    CONSTRAINT fk_message_source_message FOREIGN KEY (id)
        REFERENCES source_message (id) ON DELETE CASCADE ON UPDATE RESTRICT
);

当然,两张表的创建还有一种更便捷的方式,即yii自带的命令:

yii migrate --migrationPath=@yii/i18n/migrations/

这个命令会执行框架下的两张表的创建文件,如下:

vendor/yiisoft/yii2/i18n/migrations/m150207_210500_i18n_init.php

两种方式任一 一种执行后,数据库里都会生成这两张表。两张表的表名是可以改的,但是需要在配置文件中指定:

$sourceMessageTable 
$messageTable

二、配置i18n组件

'components' => [
  'i18n' => [
    'translations' => [
       'app' => [#对应source_message表中的category字段
           'class' => 'yii\i18n\DbMessageSource',
           // 'forceTranslation'=>true,#是否强制翻译
          'enableCaching' => false,#是否开启缓存
          //'cachingDuration' => 1 #缓存时间
          //......其他配置信息
          ]
      ],
  ],

三、创建配置文件

在需要翻译的目录,比如(frontend或者backend)目录下手动创建messages目录,执行命令:

yii message/config frontend/messages/config.php

在messages目录下生成config.php文件,内容大致如下:

return [
    'color' => null,
    'interactive' => true,
    'sourcePath' => __DIR__ . DIRECTORY_SEPARATOR . '..',#修改为待翻译目录
//    'sourcePath' => '@yii',
    'messagePath' => '@yii/messages',
    'languages' => ['zh-CN'],
    'translator' => 'Yii::t',#这里是关键,默认即可
    'sort' => false,
    'overwrite' => true,
    'removeUnused' => false,
    'markUnused' => true,
    'except' => [
        '.svn',
        '.git',
        '.gitignore',
        '.gitkeep',
        '.hgignore',
        '.hgkeep',
        '/messages',
        '/BaseYii.php',
    ],
    'only' => [
        '*.php',
    ],
    'format' => 'db',//默认生成时,是基于文件翻译,设置为db,默认是php
    'db' => 'db',//设置
    'sourceMessageTable' => '{{%source_message}}',//待翻译消息表
    'messageTable' => '{{%message}}',//翻译后消息表
    'catalog' => 'messages',
    'ignoreCategories' => [],
];

然后重新执行命令:

yii message frontend/messages/config.php

这样,两张表就会被初始化完成。最后是实现以下逻辑即可实现翻译功能。

  1. 翻译前和翻译后的文本显示逻辑
  2. 翻译后的文本存储逻辑

这样视图中基于t()方法显示的消息就会按照设置的文本显示。

最后看看Yii::t()方法到底做了什么:

1.Yii::t()是在BaseYii类中,中间调用了translate()方法

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 {
          ...          
        }
    }

2.translate()方法

public function translate($category, $message, $params, $language)
{
    #返回模式为app的原消息
    $messageSource = $this->getMessageSource($category);
    #调用父类MessageSource的translate()方法
    $translation = $messageSource->translate($category, $message, $language);
    if ($translation === false) {
        return $this->format($message, $params, $messageSource->sourceLanguage);
    } else {
        return $this->format($translation, $params, $language);
    }
}

3.MessageSource的translate()方法

public function translate($category, $message, $language)
{
    if ($this->forceTranslation || $language !== $this->sourceLanguage) {
        #翻译消息,调用DbMessageSource类的loadMessages()方法
        return $this->translateMessage($category, $message, $language);
    } else {
        return false;
    }
}

4.loadMessages()方法,根据key,以及缓冲设置进行加载

protected function loadMessages($category, $language)
{
    if ($this->enableCaching) {
        $key = [
            __CLASS__,
            $category,
            $language,
        ];
        $messages = $this->cache->get($key);
        if ($messages === false) {
            $messages = $this->loadMessagesFromDb($category, $language);
            $this->cache->set($key, $messages, $this->cachingDuration);
        }

        return $messages;
    } else {
        return $this->loadMessagesFromDb($category, $language);
    }
}

另外还有消息格式化等,请自行查阅文档使用。

参考资料
http://www.yiichina.com/doc/guide/2.0/tutorial-i18n
http://www.yiiframework.com/doc-2.0/yii-i18n-dbmessagesource.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值