什么是国际化?

国际化是为软件(在本例中为 WordPress)提供多语言支持的过程。国际化通常缩写为i18n,其中 18 代表首字母 i 和尾字母 n 之间的字母数量。

为您的插件和主题提供 i18n 支持,使其能够触达尽可能广泛的受众,即使您不需要提供额外的语言翻译。当您向 WordPress.org 上传软件时,所有 JS 和 PHP 文件将自动被解析。任何检测到的翻译字符串都会添加到 translate.wordpress.org,以便社区进行翻译,确保 WordPress 插件和主题尽可能以多种语言提供。

对于 PHP,WordPress 有一个长期建立的过程,请参阅 如何国际化您的插件。WordPress 5.0 的发布为 JavaScript 代码带来了类似的翻译过程。

如何在 JavaScript 中使用 i18n

WordPress 5.0 引入了 wp-i18n JavaScript 包,该包提供了在 PHP 中添加可翻译字符串所需的功能。

首先,在注册脚本时将 wp-i18n 添加为依赖项:

<?php
/**
 * Plugin Name: Myguten Plugin
 * Text Domain: myguten
 */
function myguten_block_init() {
    wp_register_script(
        'myguten-script',
        plugins_url( 'block.js', __FILE__ ),
        array( 'wp-blocks', 'react', 'wp-i18n', 'wp-block-editor' )
    );

    register_block_type( 'myguten/simple', array(
        'api_version' => 3,
        'editor_script' => 'myguten-script',
    ) );
}
add_action( 'init', 'myguten_block_init' );

在您的代码中,您可以包含 i18n 函数。最常用的函数是 __(双下划线),它提供简单字符串的翻译。这是一个基本块示例:

import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';

registerBlockType( 'myguten/simple', {
    apiVersion: 3,
    title: __( 'Simple Block', 'myguten' ),
    category: 'widgets',

    edit: () => {
        const blockProps = useBlockProps( { style: { color: 'red' } } );

        return <p { ...blockProps }>{ __( 'Hello World', 'myguten' ) }</p>;
    },

    save: () => {
        const blockProps = useBlockProps.save( { style: { color: 'red' } } );

        return <p { ...blockProps }>{ __( 'Hello World', 'myguten' ) }</p>;
    },
} );

在上述示例中,该函数将使用第一个参数作为要翻译的字符串。第二个参数是文本域,必须与您的插件指定的文本域标识符匹配。

可用的常见函数及其 PHP 对应项如下:

  • __( 'Hello World', 'my-text-domain' ) – 翻译特定字符串。
  • _n( '%s Comment', '%s Comments', numberOfComments, 'my-text-domain' ) – 根据提供的数字翻译并获取单数或复数形式。
  • _x( 'Default', 'block style', 'my-text-domain' ) – 带有一些额外上下文的翻译特定字符串。
注意:显示给用户的每个字符串都应包裹在 i18n 函数中。

在代码中的所有字符串都包裹后,最后一步是使用 wp_set_script_translations() 函数告诉 WordPress 您的 JavaScript 包含翻译。

<?php
    function myguten_set_script_translations() {
        wp_set_script_translations( 'myguten-script', 'myguten' );
    }
    add_action( 'init', 'myguten_set_script_translations' );

这就是使您的插件 JavaScript 代码可翻译所需的全部内容。

当您为句柄设置脚本翻译时,WordPress 将自动确定 translate.wordpress.org 上是否存在翻译文件,如果存在,则确保它在您的脚本运行之前加载到 wp.i18n 中。借助 translate.wordpress.org,插件作者也不必担心为自己的翻译设置基础设施,可以依靠拥有数十个活跃语言区域的全球社区。阅读更多关于 WordPress 翻译 的内容。

提供自己的翻译

如果您对所涉及的语言有足够的了解,您可以创建并随插件分发自己的翻译,以确保翻译可用。

创建翻译文件

翻译文件必须采用 JED 1.x JSON 格式。

要创建 JED 翻译文件,首先您需要从文本中提取字符串。通常,语言文件都位于您的插件中名为 languages 的目录内。使用 WP-CLI,您可以从插件目录中使用以下命令创建 .pot 文件:

mkdir languages
wp i18n make-pot ./ languages/myguten.pot

这将创建包含您项目中所有可翻译字符串的文件 myguten.pot。

msgid ""
msgstr ""
"Project-Id-Version: Scratch Plugin\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/scratch\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2019-03-08T11:26:56-08:00\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"X-Generator: WP-CLI 2.1.0\n"
"X-Domain: myguten\n"

#. Plugin Name of the plugin
msgid "Scratch Plugin"
msgstr ""

#: block.js:6
msgid "Simple Block"
msgstr ""

#: block.js:13
#: block.js:21
msgid "Hello World"
msgstr ""

在此处,msgid 是要翻译的字符串,而 msgstr 是实际的翻译。在 POT 文件中,msgstr 将始终为空。

然后可以使用此 POT 文件作为新翻译的模板。您应该复制该文件,使用您要翻译的语言代码,本示例将使用 Esperanto(eo)语言:

cp myguten.pot myguten-eo.po

对于这个简单示例,您可以在编辑器中简单地编辑 .po 文件,并为所有 msgstr 集添加翻译。对于更大、更复杂的翻译集,存在 GlotPress 和 Poedit 工具来提供帮助。

您还需要添加 Language: eo 参数。这是完整的 myguten-eo.po 翻译文件:

# Copyright (C) 2019
# This file is distributed under the same license as the Scratch Plugin plugin.
msgid ""
msgstr ""
"Project-Id-Version: Scratch Plugin\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/scratch\n"
"Last-Translator: Marcus Kazmierczak <marcus@mkaz.com>\n"
"Language-Team: Esperanto <marcus@mkaz.com>\n"
"Language: eo\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: 2019-02-18T07:20:46-08:00\n"
"PO-Revision-Date: 2019-02-18 08:16-0800\n"
"X-Generator: Poedit 2.2.1\n"
"X-Domain: myguten\n"

#. Plugin Name of the plugin
msgid "Scratch Plugin"
msgstr "Scratch kromprogrameto"

#: block.js:6
msgid "Simple Block"
msgstr "Simpla bloko"

#: block.js:13 block.js:21
msgid "Hello World"
msgstr "Saltuon mundo"

创建翻译文件的最后一步是将 myguten-eo.po 转换为所需的 JSON 格式。为此,您可以使用 WP-CLI 的 wp i18n make-json 命令,该命令需要 WP-CLI v2.2.0 及更高版本。

wp i18n make-json myguten-eo.po --no-purge

这将生成包含以下内容的 JSON 文件 myguten-eo-[md5].json:

{
    "translation-revision-date": "2019-04-26T13:30:11-07:00",
    "generator": "WP-CLI/2.2.0",
    "source": "block.js",
    "domain": "messages",
    "locale_data": {
        "messages": {
            "": {
                "domain": "messages",
                "lang": "eo",
                "plural-forms": "nplurals=2; plural=(n != 1);"
            },
            "Simple Block": [ "Simpla Bloko" ],
            "Hello World": [ "Salunton mondo" ]
        }
    }
}

加载翻译文件

最后一步是告诉 WordPress 在哪里查找翻译文件。wp_set_script_translations 函数接受一个可选的第三个参数,即它将首先检查翻译的路径。例如:

<?php
    function myguten_set_script_translations() {
        wp_set_script_translations( 'myguten-script', 'myguten', plugin_dir_path( __FILE__ ) . 'languages' );
    }
    add_action( 'init', 'myguten_set_script_translations' );

WordPress 将检查该路径中的文件,格式为 ${domain}-${locale}-${handle}.json 作为翻译源。或者,您可以使用文件的相对路径的 md5 哈希值代替注册的句柄,形式为 ${domain}-${locale}-${md5}.json。

使用 make-json 会自动以 md5 哈希值命名文件,因此文件可直接使用。你也可以将文件重命名为句柄名称,此时文件名将为 myguten-eo-myguten-script.json。

测试翻译

你需要将 WordPress 安装的语言设置为 Esperanto(世界语)。前往“设置” > “常规”,并将站点语言更改为世界语。

设置好语言后,创建一篇新文章,添加该区块,即可看到所使用的翻译内容。

过滤翻译

翻译函数的输出结果(__()、_x()、_n() 和 _nx())是可过滤的,有关详细信息请参阅 i18n Filters。