6.7 KiB
6.7 KiB
JavaScript/TypeScript i18n 样板
目录
概述
WooCommerce 使用来自 @wordpress/i18n 的 WordPress i18n 函数来处理可翻译字符串。像 "WooPayments" 这样的品牌名称应使用占位符以提高翻译灵活性。
import { __, sprintf } from '@wordpress/i18n';
翻译函数
基础翻译
// 简单字符串
__( '保存更改', 'woocommerce' )
// 带占位符的字符串
sprintf(
/* 译: %s: 支付提供者名称 (例如: WooPayments) */
__( '设置 %s', 'woocommerce' ),
'WooPayments'
)
使用 _n 的复数形式
import { _n, sprintf } from '@wordpress/i18n';
sprintf(
/* 译: %d: 项目数量 */
_n(
'%d 个项目已选中',
'%d 个项目已选中',
count,
'woocommerce'
),
count
)
使用 createInterpolateElement 进行插值元素
import { createInterpolateElement } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
createInterpolateElement(
sprintf(
/* translators: 1: 支付提供者名称 */
__( '为您的商店启用 <strong>%1$s</strong>。', 'woocommerce' ),
'WooPayments'
),
{
strong: <strong />,
}
)
占位符样板
单个占位符
使用 %s 表示单个占位符:
sprintf(
/* translators: %s: 支付提供者名称(例如:WooPayments) */
__( '通过 %s 收款', 'woocommerce' ),
'WooPayments'
)
多个相同占位符
当同一数值多次出现时,请使用带编号的占位符 %1$s:
sprintf(
/* translators: 1: 支付提供者名称(例如,WooPayments) */
__(
'使用 %1$s 即表示您同意我们的条款。通过 %1$s 进行的支付是安全的。',
'woocommerce'
),
'WooPayments'
)
多个不同的占位符
使用带编号的占位符 %1$s、%2$s 来表示不同的值:
sprintf(
/* translators: 1: 支付提供者名称, 2: 扩展名称 */
_n(
'正在安装 %1$s 将启用 %2$s 扩展。',
'正在安装 %1$s 将启用 %2$s 扩展。',
extensionCount,
'woocommerce'
),
'WooPayments',
extensionNames
)
译: 评论
评论位置
译者评论必须紧接在 __() 或 _n() 函数之前,而不是在 sprintf() 之前:
// ❌ 错误 - 评论在 sprintf 之前
/* translators: %s: 支付提供者名称 */
sprintf(
__( 'Set up %s', 'woocommerce' ),
'WooPayments'
)
// ✅ 正确 - 评论在 sprintf 内部,在 __() 之前
sprintf(
/* translators: %s: 支付提供者名称 */
__( 'Set up %s', 'woocommerce' ),
'WooPayments'
)
数字占位符的评论格式
当使用像 %1$s 这样的数字占位符时,在评论中只使用数字:
// ❌ 错误 - 在评论中使用 %1$s
/* translators: %1$s: Provider name, %2$s: Country */
// ✅ 正确 - 只使用数字
/* translators: 1: Provider name, 2: Country */
描述性评论
总是为译:提供上下文:
// ❌ 错误 - 无上下文
/* translators: %s: 名称 */
// ✅ 正确 - 清晰的上下文
/* translators: %s: 支付提供者名称 (例如,WooPayments) */
复杂字符串样板
结合使用 sprintf、_n 和 createInterpolateElement
installText: ( extensionsString: string ) => {
const count = extensionsString.split( ', ' ).length;
return createInterpolateElement(
sprintf(
/* translators: 1: Provider name, 2: Extension names */
_n(
'正在安装 <strong>%1$s</strong> 会启用 <strong>%2$s</strong>。',
'正在安装 <strong>%1$s</strong> 会启用 <strong>%2$s</strong>。',
count,
'woocommerce'
),
'WooPayments',
extensionsString
),
{ strong: <strong /> }
);
}
带链接的字符串
createInterpolateElement(
sprintf(
/* 译: 1: 支付提供者名称 */
__(
'了解更多关于<a>%1$s</a>的产品特点。',
'woocommerce'
),
'WooPayments'
),
{
a: (
<a
href="https://example.com"
target="_blank"
rel="noopener noreferrer"
/>
),
}
)
常见陷阱
花式撇号
TypeScript 文件可能使用花式撇号(' U+2019)而非直撇号(' U+0027)。编辑时,请保留原始字符:
// 原文使用花式撇号 - 请保留它
__( 'I don't want to install another plugin', 'woocommerce' )
// ^ 这是 U+2019,不是 U+0027
ESLint i18n 规则
@wordpress/i18n-translator-comments 规则要求注释直接位于翻译函数之前:
// ❌ ESLint 错误 - 注释未紧邻 __()
const title = sprintf(
/* translators: %s: Provider name */
__( 'Set up %s', 'woocommerce' ),
'WooPayments'
);
// ✅ 正确 - 注释直接位于 __() 之前
const title = sprintf(
/* translators: %s: Provider name */
__( 'Set up %s', 'woocommerce' ),
'WooPayments'
);
品牌名称
始终为品牌名称使用占位符以提高翻译灵活性:
// ✅ 正确 - 为品牌名称使用占位符
title: sprintf(
/* 译: %s: 支付提供者名称 */
__( '通过 %s 收款', 'woocommerce' ),
'WooPayments'
)
// ✅ 正确 - 在描述中使用占位符
description: sprintf(
/* 译: %s: 支付提供者名称 */
__( '启用 PayPal 与 %s 并存', 'woocommerce' ),
'WooPayments'
)
// ❌ 错误 - 硬编码品牌名称
title: __( '通过 WooPayments 收款', 'woocommerce' )
快速命令参考
# 检查特定文件
npx eslint client/path/to/file.tsx
# 修复特定文件
npx eslint --fix client/path/to/file.tsx
# 类型检查
pnpm run ts:check
# ❌ 从不检查整个代码库
pnpm run lint # 否 - 会检查所有内容
摘要
| 样板 | 例子 |
|---|---|
| 单个占位符 | sprintf( __( '设置 %s' ), '名称' ) |
| 重复占位符 | sprintf( __( '%1$s 通过 %1$s' ), '名称' ) |
| 多个占位符 | sprintf( __( '%1$s 在 %2$s' ), 'A', 'B' ) |
| 评论格式 (简单) | /* 译: %s: 提供者名称 */ |
| 评论格式 (带数值) | /* 译: 1: 提供者, 2: 国家 */ |