在这里新安家,先来个简单的:多语言网站,一般要考虑哪些方面呢?
代码中的文本
凡是在会在网站上显示的文字,就要考虑翻译。
服务器端,例如php,一般使用gettext模块就可以了
echo _('产品库存不足');
客户端,例如js,也可使用PHP来实现,文件名要用这种 xxx.js.php
alert('<?php echo _('产品库存不足')?>');
Note:
1. js与PHP结合,想在客户端缓存js文件,要在header加入缓存控制(Last-Modified 、Expires、Cache-Control或者 ETag 等等,根据情况返回304状态)。
2. 信息应该要更好地去组织,例如上面的出错信息可以在Error::Product_Stockout
中定义,避免了在多处代码中同一个意思却用了几种表达方式,害得翻译人员做多几次翻译。如何组织好信息及其好处,限于篇幅暂不细说。
数据表中的数据
数据表中的数据如果是要显示在页面上的,就要考虑怎样存储多种语言了。
例如产品资料,既要中文又要英文,通常会使用如下的几种方法。
- 多个语言对应多条记录
product table
product_id | language_id | name | description
- 多个语言对应多条记录
product table
product_id | language_id | name | description
- 多个语言对应多个字段
product table
product_id | name_cn | description_cn | name_en | description_en
- 多个语言对应多个表
product_cn table
product_id | name | description
product_en table
product_id | name |description
这些是基本的思路,可能会有人把多个语言都塞在一条记录的一个字段的,这些都没问题,你只要真正熟悉DB设计,平衡好系统扩展性的和效率,这些才是你首要考虑的事情。
图片、flash中的文字
资源文件要翻译唯有放在不同的语言目录,如:
img/en/banner.jpg
img/cn/banner.jpg
然后程序中将路径加上语言变量:
<img src="img/<?php echo $lang?>/banner.jpg" \>
语境与词典
同一词在不同语境下翻译不同。
例如fly,到底是苍蝇,还是要飞起来。
又如,验证,到底是要动词verify呢,还是是名词verification
这就要求我们的翻译模块要有词典功能,能切换(或合并)不同的domain。
下面是gettext的方法
// 准备环境设置
$lang = $_REQUEST['lang']; // zh_CN, en_US etc
putenv("LANG=$lang");
setlocale(LC_ALL, $lang);
bindtextdomain("general", "//path/to/general/lang/folder");
bindtextdomain("productDetail", "//path/to/productDetail/lang/folder");
textdomain("general");
// 具体应用
echo _("Label1"); // 从general module读取翻译
echo dgettext("productDetail", "Label1"); // 从productDetail module读取翻译
Zend_Translate v.s. gettext
除了gettext,Zend_Translate也是不错的选择。各有优缺点,
-
gettext中,mo文件每次改动需要重启apache才能生效,所以开发环境用Zend_Translate会方便很多。
-
gettext 在我的win7里有异常,不能翻译出en_US的,可能是系统支持的lang名称不是en_US这样的,原因未知。转用Zend_Translate瞬间解决这个问题
-
我们公司的原始文字用的是中文,然后再翻译成英文的。像这种情况,复数形式当第一个参数与第二个参数相同时,Zend_Translate不能翻译出正确的英文复数形式。而gettext可以。所以你的情况也是这样,要么想办法让参数一和二不一样(提示:利用%s与%1$s),要么就改回gettext吧
-
效率。理论上gettext是最快的,因为它会一直存在内存中。而Zend_Translate也可以使用缓存。
-
注意,gettext不是线程安全的,会有什么影响呢,参考鬼佬写的东西