Yii:多语言网站 - 最佳实践

时间:2010-03-23 02:12:31

标签: php internationalization yii

我发现Yii很棒的框架,用yiic shell创建的示例网站是一个很好的开始......但不幸的是,它没有涉及多语言网站的主题。文档涵盖了翻译短信的主题,但没有保留多语种内容......

我即将开始在一个需要至少两种语言的网站上工作,我想知道保留内容的最佳方式是什么...... 问题是内容与常见元素(如嵌入式视频文件)广泛混合。

我需要避免重复这些公共...到目前为止,我曾经有一个包含文本的数组数组(通常不超过1-2个短段),然后视图文件只是从数组中呈现文本。

现在我想避免将其保留在数组中(在引用双引号时需要注意“并且一般不方便......)。

那么,保留这些短段落的最佳方法是什么?我应该将它们保存在DB(id | msg_id | language | content)中,然后通过msg_id&amp ;;语言?这还需要我创建一些msg_id并将它们嵌入到视图文件中......

是否有任何推荐的范例Yii有一些解决方案?

谢谢, 米

4 个答案:

答案 0 :(得分:19)

Gettext很容易翻译,但默认的PHP实现不是线程安全的。因此,Yii使用自己的解包器,与php阵列相比,显着增加了处理时间。

由于我正在设置一个高容量,高交易网站,因此性能损失是不可接受的。此外,通过使用APC,我们可以缓存PHP转换,从而进一步提高性能。

因此,我的方法是使用PHP数组,但要将翻译保存在数据库中以便于翻译,在翻译时更改所需的文件。

DB类似于:

TABLE Message            // stores source language, updated by script
 id INT UNSIGNED
 category VARCHAR(20)         // first argument to Yii::t()
 key TEXT                     // second argument to Yii::t()
 occurences TINYINT UNSIGNED  // number of times found in sources

TABLE MessageTranslation // stores target language, translated by human  
 id INT UNSIGNED
 language VARCHAR(3)          // ISO 639-1 or 639-3, as used by Yii
 messageId INT UNSIGNED       // foreign key on Message table
 value TEXT
 version VARCHAR(15)
 creationTime TIMESTAMP DEFAULT NOW()
 lastModifiedTime TIMESTAMP DEFAULT NULL
 lastModifiedUserId INT UNSIGNED

然后,我修改了CLI工具yiic'message'命令,将收集的字符串转储到数据库中。

http://www.yiiframework.com/wiki/41/how-to-extend-yiic-shell-commands/

进入数据库后,可以设置一个简单的CMS,为翻译人员提供一种简单的翻译方式,同时提供版本信息,恢复旧版本,检查翻译质量等等。

另一个脚本,也是从yiic修改的,然后获取数据库信息并将其编译成PHP数组。基本上是每种语言的两个表的JOIN,然后使用'Message'构建一个数组.'key'和'MessageTranslation'。'value'as(还有什么?)key => value ...保存到以'Message'命名的文件。'category'在由language指定的文件夹中。

生成的文件由Yii CPhpMessageSource正常加载。

对于图像,这就像使用正确的语言将它们放在文件夹中并在链接时获取应用程序语言一样简单。

<img src="/images/<?php echo Yii::app()->language; ?>/help_button.png">

请注意,在现实生活中,我写了一个小帮手方法从语言字符串中删除国家,'en_us'应该是'en'。

答案 1 :(得分:17)

Yii应用程序默认使用yii :: t()方法翻译文本消息,消息来源有3种不同类型:

  1. CPhpMessageSource:翻译在PHP数组中存储为键值对。
  2. CGettextMessageSource:翻译存储为GNU Gettext文件。 (PO文件)
  3. CDbMessageSource:消息转换存储在数据库表中。
  4. 如果我没有误解,您使用经典数组进行翻译。我建议您使用带有Yii的GetText和PO文件进行翻译操作。

    您可以在official documentation page找到有关翻译和i18n的大量信息。

答案 2 :(得分:1)

我认为这里关注的是如何在页面上翻译静态文本/消息,Yii使用Yii很好地解决了它:t()和Edigu的答案就是它。

我查看FlexicaCMS上有关翻译数据库中动态内容的帖子,最终解决静态文本/消息问题后将是下一个,这是使用Yii行为的真正好方法。不确定FlexicaCMS作者是否过于雄心勃勃地支持翻译,因为它会使内容翻译变得无忧无虑 - 真的很棒。

他们没有提到的一件事是翻译页面的网址。例如your.site.com/fr/translated_article_title.html。我的意思是网址必须包含/ language_id / part,所以它可以帮助SEO。

答案 3 :(得分:0)

在Yii1和Yii2中,yii \ i18n \ GettextMessageSource无论如何都不使用Yii完美缓存引擎(查看源代码)来增强PO或MO文件的负载。不建议使用php纯代码(包括yii \ i18n \ GettextMessageSource)加载这些文件(它比php数组idx慢得多): http://mel.melaxis.com/devblog/2006/04/10/benchmarking-php-localization-is-gettext-fast-enough/

然而,MO文件的php gettext ext比转换php数组要快一些,因为它使用缓存,但负面的一点是:MO中的每次更改都需要服务器重启。

我认为最好的解决方案是在您自己的代码库中扩展yii \ i18n \ GettextMessageSource,并将缓存功能添加到GettextMessageSource以增强其性能并使用扩展版本作为组件。

protected function loadMessages($category, $language);

不要在每次加载时检查MO修改日期以与缓存进行比较,而是在更改MO或PO文件时清除缓存(可以是计划)。