本地应用程序

In Part 3 you learned some of the more important aspects of real-world localizing your application, such as using a default fallback locale and separating messages into multiple domain files depending on their usage. In this part I’ll show you what is arguably the most powerful feature of gettext – handling plural forms. The plural forms feature of gettext you enable you to localize your application perfectly and professionally.

在第3部分中,您了解了实际对应用程序进行本地化的一些更重要的方面,例如,使用默认的回退语言环境以及根据消息的使用将消息分成多个域文件。 在这一部分中,我将向您展示可以说gettext最强大的功能是什么-处理复数形式。 gettext的复数形式功能使您能够完美,专业地本地化应用程序。

复数形式 (Plural Forms)

The early programmers who first wrote messages for display to the user soon ran into a problem. When using variable numbers as part of a message, the correct form of the counted noun should be used. For example, it’s proper to say “1 file was deleted,” but “30 file was deleted” is not. The word “file” should appear in its plural form since 30 is a plural value in English.

最早编写消息以显示给用户的早期程序员很快遇到了问题。 当将可变数字用作消息的一部分时,应使用正确形式的被计数名词。 例如,说“ 1个文件已删除”是正确的,但说“ 30个文件已删除”是正确的。 “文件”一词应以复数形式出现,因为30是英语中的复数值。

An if statement is often a workaround for languages with simple grammatical cases, such as English:

对于具有简单语法情况的语言(例如英语), if语句通常是一种解决方法:

<?php
if ($i == 1) {
echo $i . " file deleted.";
}
else {
echo $i . " files deleted.";
}

If all languages followed the same grammatical numbers as English then such code would probably be sufficient. Handling plural forms might be a nuisance, but not much thought would have been given to the problem. But many languages have a richer set of grammatical numbers. In Polish, for example, plural forms differ for various numbers:

如果所有语言都遵循与英语相同的语法编号,那么这样的代码可能就足够了。 处理复数形式可能很麻烦,但是对此问题没有多加考虑。 但是许多语言的语法数字都比较丰富。 例如,在波兰语中,各种数字的复数形式有所不同:

1 plik (file)
2-4 pliki
5-21 plików
22-24 pliki
25-31 plików
...

Another example is Arabic which has at least 6 rules to define the plural forms of nouns. Obviously a hard-coded if statement is not a sustainable solution in an application that targets multiple locales!

另一个示例是阿拉伯语,它至少具有6条规则来定义名词的复数形式。 显然,在针对多个语言环境的应用程序中,硬编码的if语句不是可持续的解决方案!

Luckily gettext’s approach to the problem is much cleaner. First, you provide a rule that specifies plural forms in the header of the domain and then you provide translation messages for each of the possible plural forms. gettext then uses the rule to determine which is the correct translation to display.

幸运的是,gettext解决该问题的方法更加简洁。 首先,提供一个规则,该规则在域的标题中指定复数形式,然后为每种可能的复数形式提供翻译消息。 然后,gettext使用该规则来确定要显示的是正确的翻译。

复数形式在行动 (Plural Forms in Action)

To be able to use plural forms inside your domain, you need to write a rule for dealing with plurals for the catalog’s target language; this rule will be included in the header of the PO file telling gettext how to handle plural forms when looking up translations.

为了能够在您的域内使用复数形式,您需要为目录的目标语言编写一个处理复数的规则; 该规则将包含在PO文件的标题中,该标题告诉gettext在查找翻译时如何处理复数形式。

Create a new directory for the Polish locale (pl_PL), create the LC_MESSAGES directory and the messages.po as outlined in previous parts of this article so that now your Hello World script is Polish-enabled.

创建波兰区域设置(新目录pl_PL ),创建LC_MESSAGES目录和messages.po如本文前面的部分列出,因此现在你的Hello World脚本启用了波兰。

Open messages.po using a text editor and append the following line to its header:

使用文本编辑器打开messages.po并将以下行添加到其标题:

"Plural-Forms: nplurals=3;plural=n==1 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 || n%100>=20) ? 1 : 2;n"

and append the following to the messages lines:

并将以下内容附加到消息行:


msgid "%d file deleted."
msgid_plural "%d files deleted."
msgstr[0] "%d plik został usunięty."
msgstr[1] "%d pliki zostały usunięte."
msgstr[2] "%d plików zostało usuniętych."

Save the file, open it in Poedit, compile and close it. Then, go to test-locale.php and append the following lines:

保存文件,在Poedit中打开它,编译并关闭它。 然后,转到test-locale.php并添加以下几行:

<?php
echo "<br>";
echo ngettext("%d file deleted.", "%d files deleted.", 1);
echo "<br>";
echo ngettext("%d file deleted.", "%d files deleted.", 2);
echo "<br>";
echo ngettext("%d file deleted.", "%d files deleted.", 5);

Now when you run the script with the parameter lang=pl_PL you should see the last three lines displayed in Polish:

现在,当使用参数lang=pl_PL运行脚本时,您应该看到波兰语显示的最后三行:

1 plik został usuniętye.
2 pliki zostały usunięte.
5 plików zostało usuniętych.

复数形式规则 (The Plural Forms Rule)

Let’s take a closer look at the plural forms rule added to the header section:

让我们仔细看看添加到标题部分的复数形式规则:

"Plural-Forms: nplurals=3;plural=n==1 ? 0 : n%10>=2 && n%10< =4 && (n%100<10 || n%100>=20) ? 1 : 2;n"

The rule starts with the label “Plural-Forms:” which tells gettext the rule that follows should be used to decide which form to use given the number n. “nplurals=3” tells gettext that there are three plural forms for each noun in this locale. A semicolon then separates this from the rest of the rule.

该规则以标签“ Plural-Forms:”开头,该标签告诉gettext应该使用以下规则来确定给定数字n使用哪种形式。 “ nplurals = 3”告诉gettext在此语言环境中,每个名词都有三种复数形式。 然后用分号将其与规则的其余部分分开。

The next part of the rule starts with “plural=” and is an expression describing the selection criteria for the plural forms. It uses typical C-language syntax with a few exceptions: no negative numbers are allowed, numbers must be decimal, and the only variable allowed is n. Spaces are allowed in the expression, but backslash-escaped newlines are not.

规则的下一部分以“复数=”开头,是描述复数形式选择标准的表达式。 它使用典型的C语言语法,但有一些例外:不允许使用负数,数字必须为十进制,唯一允许的变量为n 。 表达式中允许使用空格,但不允许使用反斜杠转义的换行符。

The provided expression will be evaluated whenever one of the functions ngettext(), dngettext(), or dcngettext() is called. The numeric value passed to these functions is then substituted for all uses of the variable n. The resulting value must be greater or equal to zero but smaller than the value given as the value of nplurals. For example, if nplurals states there are three plural forms, the expression for plurals shouldn’t yield a value of 5.

每当调用函数ngettext()dngettext()dcngettext()之一时,都会评估提供的表达式。 然后,将传递给这些函数的数值替换为变量n所有用法。 结果值必须大于或等于零,但小于nplurals给出的值。 例如,如果nplurals声明存在三种复数形式,则复数的表达式不应产生值5。

The final integer calculated by the plurals expression specifies which plural form to choose for a particular n value, so if the returned integer from the expression is 0 when substituting n=1 for instance, then the plural form “0” will be used, if it equals 1, the plural form “1” will be used, and so forth.

由复数表达式计算的最终整数指定要为特定的n值选择哪种复数形式,因此,例如,当替换n=1时,如果从表达式返回的整数为0,则将使用复数形式“ 0”,如果它等于1,将使用复数形式“ 1”,依此类推。

To say the plural forms rule in words: if n is equal to 1, form “0” will be used which is plik. Otherwise if n divided by 10 returns something in the inclusive range of 2-4 and if n divided by 100 returns something less than 10 or greater than or equal to 20, form “1” will be used which is pliki, else use form “2” which is plików.

要说复数形式的规则是:如果n等于1,则将使用形式“ 0”,即plik 。 否则,如果n除以10返回的结果在2-4的范围内,并且n除以100返回的结果小于10或大于或等于20,则将使用形式“ 1”(即pliki) ,否则使用形式“ 2”,即plików

You can find plural forms rules for various language families, and more about how to translate the plural forms in your domains, by reading the GNU gettext documentation. Specifically, the Plural Forms and Translating Plural Forms sections will be the most helpful.

通过阅读GNU gettext文档,您可以找到适用于各种语言族的复数形式规则,以及有关如何在您的域中翻译复数形式的更多信息。 特别是,“复数形式”和“翻译复数形式”部分将最有帮助。

摘要 (Summary)

In this part of the localization series you saw one of the most powerful features of gettext. Programmers who may try to write their own inline if statements each time they need to present a pluralized message will soon find the approach cumbersome and fragile. Gettext abstracts the logic so you can keep your code clean. All you need to do is determine the correct expression to calculate the plural forms index for each language you translate, provide the msgid and msgid_plural pair and then a set of indexed msgstrs that gettext can choose from and gettext takes care of the rest.

在本地化系列的这一部分中,您看到了gettext的最强大功能之一。 程序员if每次需要显示多元化的信息,都可能尝试编写自己的内联if语句,他们很快就会发现这种方法既麻烦又脆弱。 Gettext抽象了逻辑,因此您可以保持代码干净。 您需要做的就是确定正确的表达式以为您翻译的每种语言计算复数形式索引,提供msgid和msgid_plural对,然后提供一组gettext可以选择的索引msgstr,gettext负责其余的工作。

The next (and final part) of the series will show you how to automate the process of extracting msgid strings from your PHP code into a template file from which you can generate your individual locale’s catalogs.

本系列的下一部分(也是最后一部分)将向您展示如何自动将PHP代码中的msgid字符串提取到模板文件中的过程,从中可以生成各个区域设置的目录。

Image via sgame / Shutterstock

图片来自sgame / Shutterstock

翻译自: https://www.sitepoint.com/localizing-php-applications-4/

本地应用程序

本地应用程序_本地化PHP应用程序的“正确方法”,第4部分相关推荐

  1. 渐进式web应用程序_渐进式Web应用程序简介

    渐进式web应用程序 Interested in learning JavaScript? Get my ebook at jshandbook.com 有兴趣学习JavaScript吗? 在jsha ...

  2. python怎么做软件程序_看 Python 超级程序员使用什么开发工具

    Python超级程序员使用的开发工具 我以个人的身份采访了几个顶尖的Python程序员,问了他们以下5个简单的问题: 当前你的主要开发任务是什么? 你在项目中使用的电脑是怎样的? 你使用什么IDE开发 ...

  3. 渐进式web应用程序_渐进式Web应用程序终极指南

    渐进式web应用程序 Progressive Web Apps, aka PWAs, are the best way for developers to make their webapps loa ...

  4. wxml 判断 小程序_如何判断小程序外包公司是否靠谱

    微信小程序依附微信App,由于其无需下载,无需安装,无需注册,直接用微信授权登录,不占内存等优势在短短2年多的时间斩获超过10亿用户.又因为微信官方开通了小程序附近五公里展示以及在微信搜一搜增加&qu ...

  5. 模型预测控制c语言程序_搭建第一个程序控制电路LED灯,体会C语言的魅力

    学习C语言,先从读程序开始!这一点是过来人的经验之谈.本文建议大家选择一款图形编程软件,本文选择了Mixly. 一.首先,介绍一下arduino UNO控制器内部电压的问题. v 高电平(5V):对应 ...

  6. pat上写java程序_如何运行Java程序和设置CLASSPAT

    导读: 如何运行JAVA和CLASSPATH环境变量的设置是学习和使用JAVA中最基本的问题,本不应在此赘述.但近来不少人在论坛上提出的问题却与此有关,我平时碰到的一些初学者也往往在这个问题上卡了壳, ...

  7. cad抛物线lisp程序_数控车宏程序编程实用干货,全在这里了...

    跟着数控技术的快速开展以及数控车技术大赛的举行,在数控车竞赛中会经常遇到复杂概括的加工,如椭圆.抛物线.双曲线等,选用常规的数控编程指令,需求计算每个节点的坐标值,不但计算量大.精度差.编程速度慢,并 ...

  8. python 自动化微信小程序_干货 | 微信小程序自动化测试最佳实践(附 Python 源码)...

    原标题:干货 | 微信小程序自动化测试最佳实践(附 Python 源码) 本文为霍格沃兹测试学院测试大咖公开课<微信小程序自动化测试>图文整理精华版. 随着微信小程序的功能和生态日益完善, ...

  9. 大小端交换的程序_数据库在小程序云开发中的应用

    " 高效率数据库为小程序·云开发赋能,共同为客户提供更多优质解决方案. " 目录 小程序·云开发介绍小程序·云开发的数据库服务解决方案及客户成功案例 小程序云开发介绍 " ...

最新文章

  1. MFC两个复选框互斥设置
  2. 即墨php,即墨php培训
  3. 十六、Redis三种特殊类型之三Bitmap
  4. python把列表写入excel_用Python将列表写入Excel文件
  5. C++Bogo Sort猴子排序的实现算法(附完整源码)
  6. [蓝桥杯2015决赛]奇怪的数列-双指针+模拟
  7. linux Ubuntu安装ftp并将本地文件上传到云服务器
  8. 设计模式原则(3)--Dependency Inversion Principle(DIP)--依赖倒转原则
  9. a6gpp php,内行人才知道的古董级玛莎拉蒂A6G 2000
  10. php 域名方法,PHP获取域名方法
  11. iOS Unicode转中文(UTF-8)
  12. html论坛注册代码,Discuz!论坛代码大全和HTML代码大全 | 穆小刚营销博客
  13. 工控协议——S7通讯协议
  14. 小朋友Stem课程制作3D打印无人机
  15. 用matlab求带参数d积分,用MATLAB求定积分
  16. win32画窗体背景
  17. 【原创】(进阶)VMware16.1.2通过PE+Dism++绕过TPM限制安装Win11首个正式原版镜像
  18. 希尔伯特变换在MATLAB中的应用
  19. Qt编写可视化大屏电子看板系统27-模块5负荷分布
  20. pytorch-自我使用笔记

热门文章

  1. NAT模式、路由模式、桥接模式 区别对比
  2. 360全景摄影的逆光问题如何解决?
  3. win11系统下安装lighttools8.6无加密狗版的方法
  4. 2020奇安信模拟笔试
  5. OSPF协议原理及配置4-邻接关系的建立和LSDB同步
  6. Python正则表达式中的r
  7. 强烈安利一波,程序猿学习网站
  8. 抓取淘宝天猫的商品的促销价格
  9. 电脑配置单5(自用勿删)
  10. 6、语句(if、switch、for、while、for...in/of、do-while、break、continue、label、return、throw、try-catch-finally、w