自动参数化

什么是自动参数化?

基本原理

<fbt> 将自动将顶级 <fbt> 中的任何非 fbt 子节点包装起来,就像它们是用包含子节点文本的 name 属性的 <fbt:param> 编写的一样。 它会将任何子节点的文本拉入参数名称,包括递归结构的文本。

  • JSX fbt 语法
<fbt desc="auto-wrap example">
Go on an
<a href="#">
<span>awesome</span> vacation
</a>
</fbt>
  • 函数语法
fbt(
[
'Go on an',
<a href="#">
<span>awesome</span> vacation
</a>,
],
'auto-wrap example',
);

提取翻译时,结果是

{
phrases: [
{
hashToLeaf: {
someHash1: {
text: 'Go on an {=awesome vacation}',
desc: 'auto-wrap example',
},
},
// ...
},
{
hashToLeaf: {
someHash2: {
text: '{=awesome} vacation',
desc: 'In the phrase: "Go on an {=awesome vacation}"',
},
},
// ...
},
{
hashToLeaf: {
someHash3: {
text: 'awesome',
desc: 'In the phrase: "Go on an {=awesome} vacation"',
},
},
// ...
},
],
childParentMappings: {
'1': 0,
'2': 1,
},
}

请注意,“vacation”的描述是自动生成的,带有 "In the phrase: ..." 前缀。 此外,我们使用约定在插值 {=awesome vacation} 中添加等号 (=) 前缀,以向翻译人员发出信号,表明这个确切的单词或短语出现在相关的外部句子中。

此外,我们在集合输出 childParentMappings 中提供映射 {<childIndex>: <parentIndex>}。 在 Meta,我们使用这些来显示翻译任何给定文本时所有相关的内部和外部字符串。 我们建议你在你使用的任何翻译框架中也这样做。 上下文对于准确的翻译至关重要。

高级场景:带有嵌套 fbt 结构的字符串

你仍然可以使用生成多个字符串的 fbt 结构(例如 <fbt:pronoun>),并期望自动参数化工作。

fbt:pronoun 和 fbt:plural 的示例

<fbt desc="advanced rich content example">
<b>
{/* Group 1 */}
<fbt:pronoun
capitalize="true"
gender={personGender}
human={true}
type="subject"
/>
</b>
{/* Group 2 */}
已上传
<Link href="#">
{/* Group 3 */}
<fbt:plural count={aCount} many="photos" showCount="ifMany">
一张照片
</fbt:plural>
</Link>
{/* Group 4 */}
你还没见过的照片.
</fbt>

顶级字符串

顶层字符串由所有文本子组的组合构建而成

`She` -------------\ /----- `{=一张照片}` -----\
`He` --------------* `上传了` * * `你还没看过的照片`
`They` -------------/ \-- `{=[数字] 张照片}` --/
^^^^^^^ ^^^^^^^^ ^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
组 1 组 2 组 3 组 4
(性别变体) (数量变体)

按字符串变体标准提取的顶层字符串

  1. 女性
    1. 单数: "{=She} 上传了 {=一张照片} 你还没看过的照片。"
    2. 复数: "{=She} 上传了 {=[数字] 张照片} 你还没看过的照片。"
  2. 男性
    1. 单数: "{=He} 上传了 {=一张照片} 你还没看过的照片。"
    2. 复数: "{=He} 上传了 {=[数字] 张照片} 你还没看过的照片。"
  3. 未知
    1. 单数: "{=They} 上传了 {=一张照片} 你还没看过的照片。"
    2. 复数: "{=They} 上传了 {=[数字] 张照片} 你还没看过的照片。"

注意: 所有这些字符串都有相同的描述: "高级富内容示例"

嵌套字符串的组合

嵌套字符串的文本和描述也将具有相关的性别/数字变体

----------------------------------------------------------------------------------------------------------------------
| 文本 | 文本 | 描述 |
| 组 1 | 组 3 | |
| (性别) | (数量) | |
----------------------------------------------------------------------------------------------------------------------
| She | {number} 张照片 | '短语中的用法: "{=She} 上传了 {=[number] 张照片} 你还没看过的照片。"' |
| She | 一张照片 | '短语中的用法: "{=She} 上传了 {=一张照片} 你还没看过的照片。"' |
| He | {number} 张照片 | '短语中的用法: "{=He} 上传了 {=[number] 张照片} 你还没看过的照片。"' |
| He | 一张照片 | '短语中的用法: "{=He} 上传了 {=一张照片} 你还没看过的照片。"' |
| They | {number} 张照片 | '短语中的用法: "{=They} 上传了 {=[number] 张照片} 你还没看过的照片。"' |
| They | 一张照片 | '短语中的用法: "{=They} 上传了 {=一张照片} 你还没看过的照片。"' |
----------------------------------------------------------------------------------------------------------------------

子父短语映射:

提交包含密切相关的字符串的翻译请求通常很有用。这有助于提高翻译的一致性(语调、词汇等),因为同一个翻译人员可以一次处理同一捆字符串。

为了支持此用例,作为 fbt-collect 输出的一部分,我们公开了 childParentMappings 属性中每个父/子字符串之间的关系。

对于每个映射条目

  • 键表示子短语的索引
  • 值表示父短语的索引
{
phrases: [
phrase_0,
phrase_1,
phrase_2,
],
childParentMappings: {
'1': 0, // 也就是说,索引 1 处的短语在索引 0 处有一个父短语
'2': 0,
},
}

fbt-collect 输出示例

{
phrases: [
{
hashToLeaf: {
c0500c5ca7453ce944fc2898b8447d07: {
text: "{=She} 上传了 {=[number] 张照片} 你还没看过的照片。",
desc: '示例',
},
'75182beb24ce6e55c815220463a0ea53': {
text: "{=She} 上传了 {=一张照片} 你还没看过的照片。",
desc: '示例',
},
'69cb3cf4329c2a81916c103240f3f2d7': {
text: "{=He} 上传了 {=[number] 张照片} 你还没看过的照片。",
desc: '示例',
},
'6f21123be92e0990409ec7727d2160ca': {
text: "{=He} 上传了 {=一张照片} 你还没看过的照片。",
desc: '示例',
},
f5ba797963f0f3e3bb7a4301d3772896: {
text: "{=They} 上传了 {=[number] 张照片} 你还没看过的照片。",
desc: '示例',
},
'0fdccf9a11f8f074ecb7234bc358526a': {
text: "{=They} 上传了 {=一张照片} 你还没看过的照片。",
desc: '示例',
},
},
// ...
},
{
hashToLeaf: {
'7b9ae98d32f354286dcae669cda85b66': {
text: 'She',
desc: '短语中的用法: "{=She} 上传了 {=[number] 张照片} 你还没看过的照片。"',
},
'710a73b38cff69aa3ffb03be0c26f0bc': {
text: 'She',
desc: '短语中的用法: "{=She} 上传了 {=一张照片} 你还没看过的照片。"',
},
'8b33671a42a9e3209be4be7eb51b64ff': {
text: 'He',
desc: '短语中的用法: "{=He} 上传了 {=[number] 张照片} 你还没看过的照片。"',
},
b600bff03f3c3f0f93d254bcedeac1b8: {
text: 'He',
desc: '短语中的用法: "{=He} 上传了 {=一张照片} 你还没看过的照片。"',
},
'94cbb79c52191ae0c66b6d4157f89e96': {
text: 'They',
desc: '短语中的用法: "{=They} 上传了 {=[number] 张照片} 你还没看过的照片。"',
},
'56f9198bf4e7da93e8347ce5a91d6999': {
text: 'They',
desc: '在短语 "{=They} 上传了 {=one photo} 一张你还没见过的照片。" 中',
},
},
// ...
},
{
hashToLeaf: {
f22d4fc3955f3e2119c6a5ee1a4d150a: {
text: '{number} 张照片',
desc: '短语中的用法: "{=She} 上传了 {=[number] 张照片} 你还没看过的照片。"',
},
a2dd015d8793b79910c6f07bed6e09cd: {
text: '一张照片',
desc: '短语中的用法: "{=She} 上传了 {=一张照片} 你还没看过的照片。"',
},
ac67b87192e6ef2b426a069cc144c649: {
text: '{number} 张照片',
desc: '短语中的用法: "{=He} 上传了 {=[number] 张照片} 你还没看过的照片。"',
},
'2520980606f16a59cfef807692e1c5cc': {
text: '一张照片',
desc: '短语中的用法: "{=He} 上传了 {=一张照片} 你还没看过的照片。"',
},
'525916bfc808cb252662573904dd75d8': {
text: '{number} 张照片',
desc: '短语中的用法: "{=They} 上传了 {=[number] 张照片} 你还没看过的照片。"',
},
'60bd72c39c28a59bee896c4f6bfa8ea9': {
text: '一张照片',
desc: '在短语 "{=They} 上传了 {=one photo} 一张你还没见过的照片。" 中',
},
},
// ...
},
],
childParentMappings: {
'1': 0,
'2': 0,
},
}
上次更新时间 by David Han Sze Chuen