支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3 / 7.2

55.2. 程式設計師篇 #

55.2.1. 機制 #

本節描述如何在屬於 PostgreSQL 發行版一部分的程式或函式庫中實作本地語言支援。 目前,它僅適用於 C 程式。

將 NLS 支援新增至程式

  1. 將此程式碼插入程式的啟動順序中

    #ifdef ENABLE_NLS
    #include <locale.h>
    #endif
    
    ...
    
    #ifdef ENABLE_NLS
    setlocale(LC_ALL, "");
    bindtextdomain("progname", LOCALEDIR);
    textdomain("progname");
    #endif
    

    (progname 實際上可以自由選擇。)

  2. 每當找到候選翻譯的訊息時,都需要插入對 gettext() 的呼叫。 例如

    fprintf(stderr, "panic level %d\n", lvl);
    

    將變更為

    fprintf(stderr, gettext("panic level %d\n"), lvl);
    

    (如果未設定 NLS 支援,則 gettext 定義為空操作。)

    這往往會增加很多混亂。 一個常見的捷徑是使用

    #define _(x) gettext(x)
    

    如果程式透過一個或幾個函數(例如後端的 ereport())進行大部分通訊,則另一種解決方案是可行的。 然後,您可以讓此函數在內部對所有輸入字串呼叫 gettext

  3. 在具有程式來源的目錄中新增檔案 nls.mk。 該檔案將被讀取為 makefile。 需要在此處進行以下變數賦值

    CATALOG_NAME

    程式名稱,如 textdomain() 呼叫中所提供。

    GETTEXT_FILES

    包含可翻譯字串的檔案清單,即那些標記有 gettext 或替代解決方案的檔案。 最終,這將包括程式的幾乎所有來源檔案。 如果此清單太長,您可以使第一個 檔案 成為 +,第二個單字成為包含每行一個檔案名稱的檔案。

    GETTEXT_TRIGGERS

    為翻譯人員產生訊息目錄的工具需要知道哪些函數呼叫包含可翻譯的字串。 預設情況下,僅知道 gettext() 呼叫。 如果您使用 _ 或其他識別碼,則需要在此處列出它們。 如果可翻譯的字串不是第一個參數,則該項目需要採用 func:2 的形式(對於第二個參數)。 如果您有一個支援複數訊息的函數,則該項目應如下所示:func:1,2(識別單數和複數訊息參數)。

  4. 新增檔案 po/LINGUAS,其中將包含提供的翻譯清單 — 最初為空。

建置系統將自動負責建置和安裝訊息目錄。

55.2.2. 訊息撰寫指南 #

以下是一些撰寫易於翻譯的訊息的指南。

  • 請勿在執行階段建構句子,例如

    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 或不為 1 時才有關係,但在其他語言中,可能存在許多不同的複數形式。 翻譯人員將兩個英文形式視為一組,並且有機會提供多個替代字串,並根據 n 的執行階段值選擇適當的一個。

    如果您需要複數化不是直接傳送到 errmsgerrdetail 報告的訊息,則必須使用底層函數 ngettext。 請參閱 gettext 文件。

  • 如果您想與翻譯人員溝通一些訊息,例如關於訊息應如何與其他輸出對齊,請在字串出現之前加上以 translator 開頭的註解,例如

    /* translator: This message is not what it seems to be. */
    

    這些註解會複製到訊息目錄檔案中,以便翻譯人員可以看到它們。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表單回報文件問題。