woocommerce/.ai/skills/woocommerce-dev-cycle/zh-cn/js-i18n-patterns.md
2026-04-15 10:18:01 +08:00

6.7 KiB
Raw Permalink Blame History

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_ncreateInterpolateElement

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: 国家 */