2 56.2. For the Programmer #
5 56.2.2. Message-Writing Guidelines
9 This section describes how to implement native language support in a
10 program or library that is part of the PostgreSQL distribution.
11 Currently, it only applies to C programs.
13 Adding NLS Support to a Program
14 1. Insert this code into the start-up sequence of the program:
22 setlocale(LC_ALL, "");
23 bindtextdomain("progname", LOCALEDIR);
24 textdomain("progname");
27 (The progname can actually be chosen freely.)
28 2. Wherever a message that is a candidate for translation is found, a
29 call to gettext() needs to be inserted. E.g.:
30 fprintf(stderr, "panic level %d\n", lvl);
33 fprintf(stderr, gettext("panic level %d\n"), lvl);
35 (gettext is defined as a no-op if NLS support is not configured.)
36 This tends to add a lot of clutter. One common shortcut is to use:
37 #define _(x) gettext(x)
39 Another solution is feasible if the program does much of its
40 communication through one or a few functions, such as ereport() in
41 the backend. Then you make this function call gettext internally on
43 3. Add a file nls.mk in the directory with the program sources. This
44 file will be read as a makefile. The following variable assignments
48 The program name, as provided in the textdomain() call.
51 List of files that contain translatable strings, i.e.,
52 those marked with gettext or an alternative solution.
53 Eventually, this will include nearly all source files of
54 the program. If this list gets too long you can make the
55 first “file” be a + and the second word be a file that
56 contains one file name per line.
59 The tools that generate message catalogs for the
60 translators to work on need to know what function calls
61 contain translatable strings. By default, only gettext()
62 calls are known. If you used _ or other identifiers you
63 need to list them here. If the translatable string is not
64 the first argument, the item needs to be of the form
65 func:2 (for the second argument). If you have a function
66 that supports pluralized messages, the item should look
67 like func:1,2 (identifying the singular and plural message
70 4. Add a file po/LINGUAS, which will contain the list of provided
71 translations — initially empty.
73 The build system will automatically take care of building and
74 installing the message catalogs.
76 56.2.2. Message-Writing Guidelines #
78 Here are some guidelines for writing messages that are easily
80 * Do not construct sentences at run-time, like:
81 printf("Files were %s.\n", flag ? "copied" : "removed");
83 The word order within the sentence might be different in other
84 languages. Also, even if you remember to call gettext() on each
85 fragment, the fragments might not translate well separately. It's
86 better to duplicate a little code so that each message to be
87 translated is a coherent whole. Only numbers, file names, and
88 such-like run-time variables should be inserted at run time into a
90 * For similar reasons, this won't work:
91 printf("copied %d file%s", n, n!=1 ? "s" : "");
93 because it assumes how the plural is formed. If you figured you
94 could solve it like this:
96 printf("copied 1 file");
98 printf("copied %d files", n):
100 then be disappointed. Some languages have more than two forms, with
101 some peculiar rules. It's often best to design the message to avoid
102 the issue altogether, for instance like this:
103 printf("number of copied files: %d", n);
105 If you really want to construct a properly pluralized message,
106 there is support for this, but it's a bit awkward. When generating
107 a primary or detail error message in ereport(), you can write
109 errmsg_plural("copied %d file",
114 The first argument is the format string appropriate for English
115 singular form, the second is the format string appropriate for
116 English plural form, and the third is the integer control value
117 that determines which plural form to use. Subsequent arguments are
118 formatted per the format string as usual. (Normally, the
119 pluralization control value will also be one of the values to be
120 formatted, so it has to be written twice.) In English it only
121 matters whether n is 1 or not 1, but in other languages there can
122 be many different plural forms. The translator sees the two English
123 forms as a group and has the opportunity to supply multiple
124 substitute strings, with the appropriate one being selected based
125 on the run-time value of n.
126 If you need to pluralize a message that isn't going directly to an
127 errmsg or errdetail report, you have to use the underlying function
128 ngettext. See the gettext documentation.
129 * If you want to communicate something to the translator, such as
130 about how a message is intended to line up with other output,
131 precede the occurrence of the string with a comment that starts
132 with translator, e.g.:
133 /* translator: This message is not what it seems to be. */
135 These comments are copied to the message catalog files so that the
136 translators can see them.