构建面向全世界的网站——gettext支持多种语言

原文地址:http://book.51cto.com/art/200905/123469.htm

构建面向全世界的网站

Web的出现使人们之间的交流简单得不可思议,通过一个Internet连接和一个Web浏览器,你就可以与任何人通信,而此时此刻也许他们正坐在莫斯科红场旁的一家咖啡店里,或者俄亥俄州的一个农舍里,也可能在上海一座摩天大楼的某个房间里,或者是以色列的一间教室里。不过对此还有一个小问题:在全部Internet民众中,只有大约29%的人讲英语 。其他人可能讲中文、日语、西班牙语、德语、法语,或者是另外几十种语言之一。因此,如果你确实希望拥有世界各地的访问者,创建网站时就应考虑不仅要符合访问者的本地语言,还要遵循一定的标准(最重要的标准包括货币、日期、数字和时间)。

不过创建全球使用的软件很困难,原因很明显:必须有适当的资源来翻译网站文本。不仅如此,还有另外一个原因,需要考虑以一种合适的方式在现有的应用程序中集成语言和标准的修改,从而防止混乱。本章将帮助你解决第二个问题。

注解 PHP 6的关键特性之一就是对Unicode(http://www.unicode.org/)的内置支持,这个标准能大大降低创建用于多种平台和支持多种语言的应用程序和网站时所带来的开销。尽管本书并不讨论Unicode和PHP的Unicode实现,不过如果可全球访问的应用程序在你的项目中是一个重要组成部分,就应该多了解一些这方面的内容。

支持本地语言和标准分为两步,要求开发人员分别完成网站的国际化(internationalize)和本地化(localize)。网站国际化是指对网站做必要的修改,以便实现本地化;本地化则是更新网站来支持具体的语言和特性。因为程序员很懒,你可能经常看到国际化(internationalization)写作i18n,本地化(localization)写作l10n。

(上面这段对国际化与本地化说得比较模糊,参考以下:

国际化是指在设计软件时,将软件与特定语言及地区脱钩的过程。当软件被移植到不同的语言及地区时,软件本身不用做内部工程上的改变或修正。本地化则是指当移植软件时,加上与特定区域设置有关的信息和翻译文件的过程。 国际化和本地化之间的区别虽然微妙,但却很重要。国际化意味着产品有适用于任何地方的“潜力”;本地化则是为了更适合于“特定”地方的使用,而另外增添的特色。用一项产品来说,国际化只需做一次,但本地化则要针对不同的区域各做一次。 这两者之间是互补的,并且两者合起来才能让一个系统适用于各地。


本节将介绍完成网站国际化和本地化时可以考虑的一种方法。

23.1 用gettext翻译网站

gettext(http://www.gnu.org/software/gettext/)是自由软件基金会(Free Software Foundation)创建和维护的众多优秀项目之一,包括许多可用于实现软件国际化和本地化的实用工具。多年来,它已经成为不计其数应用程序和网站实现内容翻译的实际标准解决方案。PHP通过一个同名扩展包与gettext交互,这说明你需要下载gettext实用工具,并在系统上安装。如果运行的是Windows平台,可以从http://gnuwin32.sourceforge.net/下载,记住一定要更新PATH环境变量以指向这个安装目录。

由于PHP的gettext扩展在默认情况下并不启用,可能还需要重新配置PHP。如果运行的是Linux,可以指定--enable-gettext选项重新构建PHP来启用这个扩展。在Windows上,所要做的只是去除php.ini文件中php_gettext.dll代码行的注释。关于配置PHP的更多信息请参见第2章。

本节余下部分将带领你完成所有必要的步骤,从而使用PHP和gettext来创建一个多语言网站。

23.1.1 第一步:更新网站脚本

gettext必须能够识别出你希望翻译哪些字符串。为此所有可翻译的输出都要通过gettext()函数传递。每次遇到gettext()时,PHP会查找特定语言的本地化库(有关内容见第二步),并将传入函数的字符串与相应的翻译匹配。由于先前调用了setlocale()以及bindtextdomain()和textdomain(),所以脚本知道获取哪个翻译。setlocale()函数告诉PHP和gettext需要遵循哪个语言和国家的约定,bindtextdomain()和textdomain()则告诉PHP在哪里查找翻译文件。

要特别注意语言和国家的记法,因为不能向setlocale()简单地传入一个语言名(如Italian),而需要选择一个预定义的语言和国家(地区)代码组合,这些组合由国际标准组织(International Standards Organization,ISO)定义。例如,你可能希望本地化为英语,但是需要使用美国的数字和时间/日期格式。在这种情况下,就要向setlocale()传入en_US,而不是传入en_GB。因为英国英语和美国英语之间的差别微乎其微,主要是一些拼法上的不同,可能只需要维护少许有差别的字符串,如果传入函数的字符串在库中未找到,则让gettext()默认为原来的字符串。

注解 许多网站上都可以找到ISO定义的语言和国家(地区)代码;只需搜索关键字ISO, country codes(国家(地区)代码)和language codes(语言代码)。表23-1提供了一个常用的代码组合的列表。

表23-1 常用国家(地区)和语言代码组合

组合

本地化环境

组合

本地化环境

pt_BR

巴西

it_IT

意大利

fr_FR

法国

es_MX

墨西哥

de_DE

德国

es_ES

西班牙

en_GB

英国

en_US

美国

he_IL

以色列

 

 

代码清单23-1给出了一个简单的例子,将字符串"Choose a password:"翻译为意大利语。

代码清单23-1 使用gettext()支持多种语言

 

当然,代码清单23-1若要正常工作,还需要创建前面提到的翻译库,并把字符串翻译为指定的语言。你将了解如何在第一步、第二步和第四步完成这些工作。

第二步:创建本地化库

接下来需要创建一个存放翻译文件的本地化库。应当为每个语言/国家(地区)代码组合分别指定一个目录,在这个目录中还需要创建另一个名为LC_MESSAGES的目录。因此,举个例子,如果打算将网站本地化为支持英语(默认语言)、德语、意大利语和西班牙语,目录结构将如下所示:

 

可以把这个目录放在你喜欢的任何位置,因为bindtextdomain()函数(代码清单23-1显示了这个函数的具体使用)会负责将这个路径映射到一个预定义域名。

第三步:创建翻译文件

接下来需要从PHP脚本抽取可翻译的字符串。可以用xgettext命令来完成,这是一个与gettext捆绑的实用工具。xgettext提供了丰富的选项,执行xgettext时通过指定--help选项可以了解各个选项的更多信息。执行以下命令将使xgettext检查当前目录中所有扩展名为.php的文件,并生成一个文件,其中包含需要翻译的字符串:

 

指定-n选项时,会在输出文件中的各个字符串前面包含文件名和行号。默认情况下,输出文件名为messages.po,不过也可以使用--default-domain=FILENAME选项改变输出文件名。以下是一个示例输出文件:

 
 

把这个文件复制到适当的本地化目录,继续下一步。

第四步:翻译文本

打开你要翻译的语言目录中的messages.po文件,通过完成与抽取字符串对应的空msgstr项来翻译这些字符串。然后将用全大写字母表示的占位符替换为你的应用程序的相关信息。要特别注意CHARSET占位符,因为你使用的具体值将直接影响gettext最终翻译应用程序的能力。需要将CHARSET替换为用于表示所翻译字符串的适当字符集的名字。例如,字符集ISO-8859-1用于表示使用拉丁文字母的语言,包括英语、德语、意大利语和西班牙语。Windows-1251用于表示使用斯拉夫语字母的语言,包括俄语。这里并不打算逐一介绍数不胜数的各种字符集,建议从http://en.wikipedia.org/wiki/ Character_encoding查看最全面的Wikipedia总结。

提示 要用某种本地语言写出地道的文本确实很困难,所以如果想把你的网站翻译成另一种语言,最好找一位擅长这种语言的人提供帮助。专业的翻译服务可能成本很高,所以可以考虑联系当地的大学,通常大学里会有很多外国学生,他们会很欢迎有这种机会来获得一些经验,而且费用往往相当便宜。

第五步:生成二进制文件

之后一个必要的步骤是生成messages.po文件的二进制版本,gettext将使用这些二进制文件。这个工作使用msgfmt命令完成。切换到适当的语言目录,并执行以下命令:

 

执行这个命令将生成名为messages.mo的文件,这就是gettext最终用来完成翻译的文件。类似于xgettext,msgfmt也通过选项提供了丰富的特性。执行msgfmt --help可以了解这个工具提供了哪些选项。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值