本节描述如何在 PostgreSQL 发行版中包含的程序或库中实现本地语言支持。目前,它仅适用于 C 程序。
向程序添加 NLS 支持
将此代码插入程序的启动序列
#ifdef ENABLE_NLS #include <locale.h> #endif ... #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bindtextdomain("progname
", LOCALEDIR); textdomain("progname
"); #endif
(progname
实际上可以自由选择。)
在找到可能需要翻译的消息时,需要插入对 gettext()
的调用。例如
fprintf(stderr, "panic level %d\n", lvl);
将更改为
fprintf(stderr, gettext("panic level %d\n"), lvl);
(如果未配置 NLS 支持,则 gettext
定义为无操作。)
这往往会增加很多杂乱。一个常见的捷径是使用
#define _(x) gettext(x)
如果程序通过一个或几个函数(例如后端的 ereport()
)进行大部分通信,则另一种解决方案是可行的。然后,您使此函数在所有输入字符串上内部调用 gettext
。
在包含程序源代码的目录中添加一个文件 nls.mk
。此文件将作为 Makefile 读取。此处需要进行以下变量赋值
CATALOG_NAME
程序名称,如 textdomain()
调用中提供的。
GETTEXT_FILES
包含可翻译字符串的文件列表,即用 gettext
或替代方案标记的文件。最终,这将包含程序的几乎所有源文件。如果此列表变得过长,您可以使第一个 “文件” 为 +
,第二个单词为包含每行一个文件名且文件。
GETTEXT_TRIGGERS
用于为翻译人员生成消息目录的工具需要知道哪些函数调用包含可翻译字符串。默认情况下,仅识别 gettext()
调用。如果您使用了 _
或其他标识符,则需要在此处列出它们。如果可翻译字符串不是第一个参数,则该项需要采用 func:2
的形式(用于第二个参数)。如果您有一个支持复数消息的函数,则该项应类似于 func:1,2
(标识单数和复数消息参数)。
添加一个文件 po/LINGUAS
,其中将包含提供的翻译列表 - 最初为空。
构建系统将自动处理消息目录的构建和安装。
以下是一些关于编写易于翻译的消息的指南。
不要在运行时构建句子,例如
printf("Files were %s.\n", flag ? "copied" : "removed");
其他语言中的句子词序可能不同。此外,即使您记得在每个片段上调用 gettext()
,这些片段也可能无法单独翻译。最好复制少量代码,以便每个要翻译的消息都是一个连贯的整体。只有数字、文件名以及类似的运行时变量应在运行时插入消息文本中。
出于类似的原因,这将不起作用
printf("copied %d file%s", n, n!=1 ? "s" : "");
因为它假设了复数是如何形成的。如果您认为可以通过以下方式解决它
if (n==1) printf("copied 1 file"); else printf("copied %d files", n):
那么您会失望的。某些语言有两种以上的形式,并且有一些特殊的规则。通常最好设计消息以完全避免此问题,例如
printf("number of copied files: %d", n);
如果您确实想构建一个正确的复数消息,则支持此功能,但有点笨拙。在 ereport()
中生成主要或详细错误消息时,您可以编写如下内容
errmsg_plural("copied %d file", "copied %d files", n, n)
第一个参数是适合英语单数形式的格式字符串,第二个参数是适合英语复数形式的格式字符串,第三个参数是确定使用哪种复数形式的整数控制值。后续参数根据格式字符串按通常方式进行格式化。(通常,复数化控制值也将是要格式化的值之一,因此必须写入两次。)在英语中,只有 n
是否为 1 才有关系,但在其他语言中可能有许多不同的复数形式。翻译人员将两种英语形式视为一组,并有机会提供多个替换字符串,根据 n
的运行时值选择合适的字符串。
如果您需要复数化不直接发送到 errmsg
或 errdetail
报告的消息,则必须使用底层函数 ngettext
。请参阅 gettext 文档。
如果您想向翻译人员传达某些信息,例如关于消息如何与其他输出对齐的信息,请在字符串出现之前加上以 translator
开头的注释,例如
/* translator: This message is not what it seems to be. */
这些注释被复制到消息目录文件中,以便翻译人员可以看到它们。
如果您在文档中发现任何不正确的内容,与您对特定功能的体验不符,或者需要进一步澄清,请使用此表单 报告文档问题。