在本文中,您将了解何时以及如何使用所有可用的 i18n 函数,以及编写字符串的最佳实践。
本文中的建议同时适用于您的 PHP 和 JavaScript 代码。您可以在 I18n functions 页面查看所有语言可用的函数。JavaScript 可用的函数也将被高亮显示。
基本字符串
最常用的函数是 __()。它返回其参数的翻译:
__( 'Blog Options', 'my-theme' );另一个简单的函数是 _e(),它输出其参数的翻译。与其写成:
echo __( 'WordPress is the best!', 'my-theme' );您可以使用更短的写法:
_e( 'WordPress is the best!', 'my-theme' );__() 也适用于 JavaScript
变量
如果您在字符串中使用变量,如下面的示例所示,您需要使用占位符。
echo 'Your city is $city.'请使用 printf 系列的函数。特别是 printf 和 sprintf 非常有用。例如:
printf(
/* translators: %s: Name of a city */
__( 'Your city is %s.', 'my-theme' ),
$city
);请注意,用于翻译的字符串是模板 "Your city is %s.",它在源代码和运行时都是相同的。
如果字符串中有多个占位符,建议使用 参数交换。在这种情况下,必须使用单引号 ('):双引号 (") 会告诉 PHP 将 $s 解释为 s 变量,这不是我们想要的。
printf(
/* translators: 1: Name of a city 2: ZIP code */
__( 'Your city is %1$s, and your zip code is %2$s.', 'my-theme' ),
$city,
$zipcode
);在这里,邮政编码显示在城市名称之后。在某些语言中,以相反的顺序显示邮政编码和城市更为合适。使用 %s 前缀(如上例所示)允许这样做。翻译可以写成:
printf(
/* translators: 1:ZIP code 2:Name of a city */
__( 'Your zip code is %2$s, and your city is %1$s.', 'my-theme' ),
$city,
$zipcode
);sprintf 也适用于 JavaScript 翻译:
const zipCodeMessage = sprintf(
/* translators: 1:ZIP code 2:Name of a city */
__( 'Your zip code is %2$s, and your city is %1$s.', 'my-theme'),
city,
zipcode
);以下示例告诉您不应该做什么
这是错误的。
// This is incorrect do not use.
_e( "Your city is $city.", 'my-theme' );用于翻译的字符串是从源代码中提取的,而不执行相关的 PHP。例如:变量 $city 可能是温哥华,所以当模板运行时,您的字符串将是 "Your city is Vancouver",但 gettext 无法提前知道 PHP 变量内部的内容。
由于在翻译字符串时变量的值未知,这将要求翻译人员知道变量 $country 的每一种情况。这并不理想,最好移除动态内容,让翻译人员专注于静态内容。
复数形式
基本复数化
如果您有一个随项目数量变化而变化的字符串。在英语中,您有 "One comment" 和 "Two comments"。在其他语言中,可能有多种复数形式。要在 WordPress 中处理这种情况,您可以使用 _n() 函数。
printf(
_n(
'%s comment',
'%s comments',
get_comments_number(),
'my-theme'
),
number_format_i18n( get_comments_number() )
);_n() 接受 4 个参数:
- singular – 字符串的单数形式(注意:在某些语言中,它可用于非一的数字,因此应使用
'%s item'而不是'One item') - plural – 字符串的复数形式
- count – 对象的数量,它将决定是返回单数还是复数形式(有些语言有远超两种的形式)
- text domain – 主题的文稿域
函数的返回值是对应于给定计数的正确翻译形式。
`_n() 也适用于 JavaScript稍后处理复数化
您首先使用 _n_noop() 或 _nx_noop() 设置复数字符串。
$comments_plural = _n_noop(
'%s comment.',
'%s comments.'
);在代码的稍后阶段,您可以使用 translate_nooped_plural() 来加载这些字符串。
printf(
translate_nooped_plural(
$comments_plural,
get_comments_number(),
'my-theme'
),
number_format_i18n( get_comments_number() )
);通过上下文消除歧义
有时一个术语在多个上下文中使用,即使英语中对每个上下文使用同一个词,也必须用其他语言分别翻译。例如,单词 Post 既可以用作动词 "Click here to post your comment",也可以用作名词 "Edit this Post"。在这种情况下,应使用 _x() 或 _ex() 函数。它与 __() 和 _e() 类似,但多了一个参数——上下文:
_x( 'Post', 'noun', 'my-theme' );
_x( 'post', 'verb', 'my-theme' );在这两种情况下使用此方法,我们会得到原文的 Comment 字符串。但是,翻译人员将看到两个用于翻译的 Comment 字符串,每个都在不同的上下文中。
以 WordPress 德语版本为例:Post 是 Beiträge。德语中相应的动词形式是 beitragen。
请注意,与 __() 类似,_x() 也有一个 echo 版本:_ex()。前面的例子可以写成:
_ex( 'Post', 'noun', 'my-theme' );
_ex( 'post', 'verb', 'my-theme' );使用您觉得能提高可读性和编码便利性的那个。
_x() and _nx()也适用于 JavaScript描述
您可以在源代码中添加澄清注释,以便翻译人员知道如何翻译像 __( 'g:i:s a' ) 这样的字符串。它必须以单词 translators: 开头(全部小写),并且必须是 gettext 调用之前的最后一个 PHP 注释。这里有一个示例:
/* translators: draft saved date format, see http://php.net/date */
$saved_date_format = __( 'g:i:s a' );多行示例:
/*
* translators: Replace with a city related to your locale.
* Test that it matches the expected location and has upcoming
* events before including it. If no cities related to your
* locale have events, then use a city related to your locale
* that would be recognizable to most users.
*/
?>
<input placeholder="<?php esc_attr_e( 'Cincinnati' ); ?>" id="location" type="text" name="location" />换行符
Gettext 不喜欢可翻译字符串中的 r(ASCII 码:13),所以请避免使用它,改用 n。
空字符串
空字符串保留用于 Gettext 的内部使用,您必须不要尝试国际化空字符串。这也毫无意义,因为翻译人员将没有上下文。
如果您有国际化空字符串的有效用例,请为两者添加上下文,以帮助翻译人员并符合 Gettext 系统的要求。
转义字符串
转义所有字符串是个好习惯,可以防止翻译人员运行恶意代码。有一些与国际化函数集成的转义函数。
<a title="<?php esc_attr_e( 'Skip to content', 'my-theme' ); ?>" class="screen-reader-text skip-link" href="#content" >
<?php _e( 'Skip to content', 'my-theme' ); ?>
</a><label for="nav-menu">
<?php esc_html_e( 'Select Menu:', 'my-theme' ); ?>
</label>编写字符串的最佳实践
以下是编写字符串的最佳实践
- 使用规范的英语风格——尽量减少俚语和缩写。
- 使用完整的句子——在大多数语言中,词序与英语不同。
- 按段落拆分——合并相关句子,但不要在单个字符串中包含整页文本。
- 不要留下可翻译短语中的首尾空格。
- 假设翻译后的字符串长度可能翻倍。
- 避免使用特殊标记和控制字符——不要包含包围你文本的标签。
- 不要在可翻译字符串中添加不必要的 HTML 标记。
- 不要留下 URL 供翻译,除非它们可能有其他语言版本。
- 将变量作为占位符添加到字符串中,因为在某些语言中占位符的位置会发生变化。
printf(
__( 'Search results for: %s', 'my-theme' ),
get_search_query()
);- 使用格式字符串代替字符串连接——翻译短语而不是单词——
printf(
__( 'Your city is %1$s, and your zip code is %2$s.', 'my-theme' ),
$city,
$zipcode
);总是优于
__( 'Your city is ', 'my-theme' ) . $city . __( ', and your zip code is ', 'my-theme' ) . $zipcode;- 尽量使用相同的单词和符号,以防止翻译多个相似的字符串(例如,不要执行以下操作)
__( 'Posts:', 'my-theme' ); and __( 'Posts', 'my-theme' );