将PHP应用程序本地化为“正确的方式”,第5部分

tech2023-12-04  80

In Part 4 you learned how to use gettext for one of the most complex aspects of localization a developer can face, plural forms. In this, the final part of the five-part series, I’ll teach you how you to automate part of the localization process by extracting msgids and generating a PO template file (.pot) from your application’s PHP code. Let’s dive right in!

在第4部分中,您学习了如何将gettext用于开发人员可以面对的最复杂的本地化方面之一,即复数形式。 在本部分(共五部分)中,我将教您如何通过提取msgids并从应用程序PHP代码生成PO模板文件( .pot )来自动化部分本地化过程。 让我们潜入吧!

从源中提取字符串 (Extracting Strings from Source)

You’ve seen how powerful gettext is, and how easy it was to incorporate localization into your applications. But what about ongoing maintenance? As your application matures, text strings are sure to be added, updated, and removed. Extracting strings for use as msgids and organizing them by hand is a daunting task, even with just a small codebase. Here’s where xgettext can help.

您已经了解到gettext有多么强大,以及将本地化合并到应用程序中有多么容易。 但是正在进行的维护又如何呢? 随着应用程序的成熟,一定要添加,更新和删除文本字符串。 即使仅使用很小的代码库,提取用作msgids的字符串并手工组织它们也是一项艰巨的任务。 这是xgettext可以提供帮助的地方。

xgettext is a command-line tool that is part of the gettext library which you downloaded and installed in Part 1… a very useful tool indeed! Its purpose is to simplify the extraction of strings from your source code and generate a domain template, thereby saving you time and hassle. xgettext is not PHP specific; you can use it to extract strings from code written in over 15 popular programming languages, including C, C++, C#, Java, Perl, PHP, and Python to name just a few.

xgettext是一个命令行工具,是您在第1部分中下载并安装的gettext库的一部分……确实是一个非常有用的工具! 其目的是简化从源代码中提取字符串并生成域模板的过程,从而节省时间和麻烦。 xgettext不是特定于PHP的; 您可以使用它从以15种流行编程语言编写的代码中提取字符串,这些语言包括C,C ++,C#,Java,Perl,PHP和Python等。

Before you begin, make sure your Test18N directory is up to date with the following structure created in the previous parts of this series.

在开始之前,请确保您的Test18N目录是最新的,并且在本系列前面的部分中创建了以下结构。

Open test_locale.php and replace its contents with the following code:

打开test_locale.php并将其内容替换为以下代码:

<?php require_once "locale.php"; echo _("Hello World!") . "<br>"; echo _("Testing Translation...") . "<br>"; echo _("Please login first:") . "<br>"; echo _("Click on the link below") . "<br>"; echo _("Shutdown system") . "<br>"; echo '<a href="test_page_1.php">' . _("Go To Page 1") . "</a>";

Then, create a new file named test_page_1.php with the following contents:

然后,创建一个名为test_page_1.php的新文件,其内容如下:

<?php require_once "locale.php"; echo _("Errors occurred") . "<br>"; echo _("Please fix this") . "<br>"; echo _("Click on the link below") . "<br>"; echo dgettext("errors", "Error getting content") . "<br>"; echo dgettext("errors", "Error saving data") . "<br>"; echo '<a href="test_locale.php">' . _("Back To Home") . '</a>&nbsp;|&nbsp;<a href="test_page_2.php">' . _("Go To Page 2") . "</a>";

And finally, create a new file named test_page_2.php with the following contents:

最后,创建一个名为test_page_2.php的新文件,其内容如下:

<?php require_once "locale.php"; echo _("If you want to read more") . "<br>"; echo _("Please login first:") . "<br>"; echo sprintf(ngettext("%d file", "%d files", 1), 1) . "<br>"; echo sprintf(ngettext("%d file", "%d files", 2), 2) . "<br>"; echo sprintf(ngettext("%d file", "%d files", 5), 5) . "<br>"; echo '<a href="test_locale.php">' . _("Back To Home") . '</a>&nbsp;|&nbsp;<a href="test_page_1.php">' . _("Go To Page 1") . "</a>";

Now you should have three files to emulate a slightly larger application. And like a real-world app would have, you’ll notice that some messages are repeated in more than one file. If you were to extract the strings by hand, you’d have to sort them and remove any duplicates when creating your translation file.

现在,您应该有三个文件来模拟稍大的应用程序。 就像现实世界中的应用程序一样,您会注意到某些消息在多个文件中重复出现。 如果要手工提取字符串,则在创建翻译文件时必须对它们进行排序并删除所有重复项。

Now for the magic of automation. Open a terminal window, go to the Test18N directory, and run the following command:

现在是自动化的魔力。 打开一个终端窗口,转到Test18N目录,然后运行以下命令:

abouzekry@sandbox:~/htdocs/Test18N$ xgettext --from-code=UTF-8 -o messages.pot *.php

This instructs xgettext to extract messages from all the PHP files in the current directory. xgettext assumes any file is ASCII by default, and its output may contain unexpected results if the source strings contain any non-ASCII characters. To be on the safe side I’ve overridden its assumption with UTF-8 using the --from-code option. The -o option instructs xgettext to write its output to a file named messages.pot, the base file you’ll be using shortly for all your translations.

这指示xgettext从当前目录中的所有PHP文件中提取消息。 xgettext假定默认情况下任何文件都是ASCII,并且如果源字符串包含任何非ASCII字符,则其输出可能包含意外结果。 为了安全起见,我使用--from-code选项以UTF-8覆盖了它的假设。 -o选项指示xgettext将其输出写入名为messages.pot的文件中,该文件将很快用于所有翻译。

Before going any further, it’s worth noting that xgettext has some limitations. Most noticeably it writes all the strings to a single file (test_page_1.php for example uses dgettext() to look up some of the translations in the errors domain, but the strings have all been put into messages.pot). You can either use only a single domain, or you can split messages.pot afterwards into the appropriate files. I really like having specialized translation domains to keep everything organized, so this is the approach I will encourage here.

在进一步介绍之前,值得注意的是xgettext有一些限制。 最值得注意的是它会将所有的字符串到一个文件中( test_page_1.php例如使用dgettext()来查找一些错误域的翻译,但琴弦已全部投入messages.pot )。 您可以只使用一个域,也可以随后将messages.pot拆分为适当的文件。 我真的很喜欢拥有专门的翻译领域来保持一切井井有条,因此我将在此鼓励这种方法。

Copy the file messages.pot as errors.pot and edit errors.pot to remove all of the messages except those relating to the errors domain. You should keep only the following messages:

将文件messages.pot复制为errors.pot并编辑errors.pot以删除除与错误域有关的所有消息。 您应该只保留以下消息:

#: test_page_1.php:9 msgid "Error getting content" msgstr "" #: test_page_1.php:10 msgid "Error saving data" msgstr ""

Then, edit messages.pot to remove the error-related messages from that file.

然后,编辑messages.pot从该文件中删除与错误相关的消息。

使用模板 (Using the Templates)

Now you have two templates to start with, one for the messages domain (messages.pot) and another for the errors domain (domain.pot). Start Poedit, choose File > New catalog from POT file, and open messages.pot.

现在,您有两个模板开始,一个用于消息域( messages.pot ),另一个用于错误域( domain.pot )。 启动Poedit, New catalog from POT file选择“ File >“ New catalog from POT file ,然后打开messages.pot 。

Fill the necessary parameters as outlined before in Part 2. I will be creating a French language catalog using the UTF-8 encoding. It’s also important to specify the appropriate plural forms expression, too. For French, it is “nplurals=2; plural=n>1;”. After you click OK, you’ll be asked to save the new PO file created from the template. Save it as the corresponding Locale/fr_FR/LC_MESSAGES/messages.po file.

填写第2部分中之前概述的必要参数。 我将使用UTF-8编码创建法语目录。 指定合适的复数形式表达式也很重要。 对于法语,它是“ nplurals = 2; 复数= n> 1;”。 单击确定后,将要求您保存从模板创建的新PO文件。 将其另存为相应的Locale/fr_FR/LC_MESSAGES/messages.po文件。

Poedit then opens the PO file and displays the original strings and their translations. You can add your translations directly in Poedit, or send the file off to your translator to work on while you focus on your application’s PHP code.

然后,Poedit将打开PO文件并显示原始字符串及其翻译。 您可以直接在Poedit中添加翻译,也可以将文件发送给您的翻译器,以专注于应用程序PHP代码。

As a side note, dealing with plural forms in Poedit’s interface is easy. When you click on the singular form in the translation list, you’ll see tabs at the bottom for each form in which you can input appropriate translations.

附带说明一下,在Poedit界面中处理复数形式很容易。 当您单击翻译列表中的单数形式时,您会在每种形式的底部看到标签,您可以在其中输入适当的翻译。

Once you’re finished providing the translations for each msgid, choose File > Save or click the Save Catalog entry in the icon bar to save and generate the necessary MO file. Then do the same procedure for errors.pot, saving it to Locale/fr_FR/LC_MESSAGES/errors.po. You’ll need to repeat the process for each template for each language you have.

为每个msgid提供完翻译后,请选择“ File >“ Save或单击图标栏中的“ Save Catalog条目以保存并生成必要的MO文件。 然后对errors.pot执行相同的过程,将其保存到Locale/fr_FR/LC_MESSAGES/errors.po 。 您需要为每种模板针对每种语言重复该过程。

When at least the French locale’s MO files are in place, test the test-locale.php script to make sure everything is working.

至少在法语区域设置的MO文件到位后,测试test-locale.php脚本以确保一切正常。

摘要 (Summary)

In this last part of the series, you learned how to extract translation strings automatically from your PHP source files using the xgettext tool, generating a PO template file. The template can then be used for generating any target domain catalogs you need, thus leaving the cumbersome process of messages extraction to the computer.

在本系列的最后一部分中,您学习了如何使用xgettext工具从PHP源文件中自动提取翻译字符串,并生成PO模板文件。 然后,可以将模板用于生成所需的任何目标域目录,从而将繁琐的邮件提取过程留给计算机。

Throughout the five parts you’ve learned how localization can be just a matter of writing separate translation files for a target locale, and then referenced using gettext(), its shorthand alias _(), and its plural counterpart ngettext(). You’ve also seen how taking advantage of gettext’s fallback behavior can lead to more readable code and translation catalogs, and how translations can be neatly organized into their own domains (messages.po for general messages, errors.po for error strings, etc.).

在这五个部分中,您已经了解了本地化的方法仅仅是为目标语言环境编写单独的翻译文件,然后使用gettext() ,其简写别名_()以及其复数形式的ngettext() 。 您还了解了如何利用gettext的后备行为可以使代码和翻译目录更具可读性,以及如何将翻译整齐地组织到自己的域中( messages.po表示常规消息, errors.po表示错误字符串等)。 )。

I’ve enjoyed writing this series and want to thank you for taking the time to learn how to localize your PHP applications “the right way” with gettext. gettext really is a wonderful open-source tool that helps make your life easier by allowing you to concentrate on your code.

我很喜欢撰写本系列文章,并感谢您花时间学习如何使用gettext“正确的方式”本地化PHP应用程序。 gettext确实是一个很棒的开源工具,它使您可以专注于代码,从而使生活变得更轻松。

Image via sgame / Shutterstock

图片来自sgame / Shutterstock

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

相关资源:jdk-8u281-windows-x64.exe
最新回复(0)