JSON 中的分块结构

本文档将介绍如何使用 JSON 定义块中的输入、字段(包括标签)和连接。如果您不熟悉这些术语,请先参阅代码块剖析,然后再继续。

您还可以在 JavaScript 中定义输入、字段和连接。

概览

在 JSON 中,您可以使用一个或多个消息字符串 (message0message1、…) 及其对应的参数数组 (args0args1、…) 来描述代码块的结构。消息字符串由文本(转换为标签)和插值令牌 (%1%2、…) 组成,用于标记连接和非标签字段的位置。实参数组介绍了如何处理插值令牌。

例如,以下代码块:

由以下 JSON 定义:

JSON

{
  "message0": "set %1 to %2",
  "args0": [
    {
      "type": "field_variable",
      "name": "VAR",
      "variable": "item",
      "variableTypes": [""]
    },
    {
      "type": "input_value",
      "name": "VALUE"
    }
  ]
}

第一个插值令牌 (%1) 表示变量字段 (type: "field_variable")。它由 args0 数组中的第一个对象描述。第二个令牌 (%2) 表示值输入 (type: "input_value") 末尾的输入连接。它由 args0 数组中的第二个对象描述。

消息和输入

插值令牌标记连接时,实际上是在标记包含连接的输入的结束。这是因为值和语句输入中的连接会在输入结束时呈现。输入包含上一个输入之后到当前令牌的所有字段(包括标签)。以下部分显示了消息示例以及根据这些消息创建的输入。

示例 1

JSON

{
  "message0": "set %1 to %2",
  "args0": [
    {"type": "field_variable", ...} // token %1
    {"type": "input_value", ...}    // token %2
  ],
}

这会创建一个包含三个字段的单值输入:一个标签 ("set")、一个变量字段和另一个标签 ("to")。

将消息“将 %1 设为 %2”映射到包含三个字段的值输入。

示例 2

JSON

{
  "message0": "%1 + %2",
  "args0": [
    {"type": "input_value", ...} // token %1
    {"type": "input_value", ...} // token %2
  ],
}

这会创建两个值输入。第一个没有字段,第二个有一个字段 ("+")。

将消息“%1 + %2”映射到两个值输入。

示例 3

JSON

{
  "message0": "%1 + %2 %3",
  "args0": [
    {"type": "input_value", ...}   // token %1
    {"type": "input_end_row", ...} // token %2
    {"type": "input_value", ...}   // token %3
  ],
}

这会创建:

  • 不含字段的值输入
  • 带有标签字段 ("+") 的行尾输入,这会导致以下值输入在新的行上呈现,
  • 不含字段的值输入。

将消息“%1 + %2 %3”映射到两个值输入和一个行尾输入。

邮件末尾的虚构输入

如果您的 message 字符串以文本或字段结尾,则无需为包含这些内容的虚构输入添加插值令牌,Blockly 会为您添加。例如,请勿像这样定义 lists_isEmpty 块:

JSON

{
  "message0": "%1 is empty %2",
  "args0": [
    {"type": "input_value", ...} // token %1
    {"type": "input_dummy", ...} // token %2
  ],
}

将消息“%1 为空”映射到值输入和自动创建的虚构输入。

您可以让 Blockly 添加虚构输入,并按如下方式进行定义:

JSON

{
  "message0": "%1 is empty",
  "args0": [
    {"type": "input_value", ...} // token %1
  ],
}

将消息“%1 为空”映射到值输入和自动创建的虚构输入。

自动添加尾随虚构输入后,译者无需修改描述插值令牌的参数,即可更改 message。如需了解详情,请参阅插值令牌顺序

implicitAlign

在极少数情况下,自动创建的尾随虚构输入需要与 "RIGHT""CENTRE" 对齐。如果未指定,默认值为 "LEFT"

在以下示例中,message0"send email to %1 subject %2 secure %3",并且 Blockly 会自动为第三行添加虚构输入。将 implicitAlign0 设置为 "RIGHT" 会强制将此行右对齐。

implicitAlign 适用于 JSON 块定义中未明确定义的所有输入,包括用于替换换行符 ('\n') 的行尾输入。此外,还有已废弃的属性 lastDummyAlign0,其行为与 implicitAlign0 相同。

为 RTL(阿拉伯语和希伯来语)设计块时,左侧和右侧会相反。因此,"RIGHT" 会将字段左对齐。

多条消息

有些代码块会自然地分为两个或更多个单独的部分。请考虑以下包含两行的重复代码块:

如果使用一条消息描述此块,message0 属性将为 "repeat %1 times %2 do %3",其中 %2 表示行尾输入。此字符串对译者来说很难处理,因为很难解释 %2 替换项的含义。在某些语言中,%2 行尾输入可能根本不需要。并且可能有多个块希望共享第二行的文本。更好的方法是使用多个 messageargs 属性:

JSON

{
  "message0": "repeat %1 times",
  "args0": [
    {"type": "input_value", ...} // token %1 in message0
  ],
  "message1": "do %1",
  "args1": [
    {"type": "input_statement", ...} // token %1 in message1
  ],
}

将消息“repeat %1 times”映射到值输入和自动创建的虚构输入,将消息“do %1”映射到语句输入。

您可以使用 JSON 格式定义任意数量的 messageargsimplicitAlign 属性,从 0 开始,按顺序递增。请注意,Block Factory 无法将消息拆分为多个部分,但手动执行此操作非常简单。

插值令牌顺序

本地化代码块时,您可能需要更改消息中插值令牌的顺序。对于与英语词序不同的语言,这一点尤为重要。例如,我们先从消息 "set %1 to %2" 定义的块开始:

现在假设一种语言,其中 "set %1 to %2" 需要反向读取才能读出 "put %2 in %1"。更改消息(包括插值令牌的顺序)并让参数数组保持不变,会生成以下代码块:

Blockly 会自动更改字段的顺序、创建虚构输入,并从外部输入切换为内部输入。

能够更改消息中插值令牌的顺序,有助于简化本地化工作。如需了解详情,请参阅 JSON 消息插值

文本处理

插值令牌两侧的文本会被修剪掉空格。使用字符 % 的文本(例如引用百分比时)应使用 %%,以免被解读为插值令牌。

Blockly 还会自动将消息字符串中的所有换行符 (\n) 替换为行尾输入。

JSON

{
  "message0": "set %1\nto %2",
  "args0": [
    {"type": "field_variable", ...}, // token %1
    {"type": "input_value", ...},    // token %2
  ]
}

将“set %1\nto %2”中的换行符映射到行尾输入。

参数数组

每个消息字符串都与一个数量相同的 args 数组配对。例如,message0args0 搭配使用。插值令牌 (%1%2、…) 引用 args 数组中的项,并且必须与 args0 数组完全匹配:不得重复,也不得遗漏。令牌编号是指实参数组中项的顺序;它们在消息字符串中出现的顺序不必一致。

参数数组中的每个对象都有一个 type 字符串。其余参数因类型而异:

您还可以定义自己的自定义字段自定义输入,并将它们作为参数传递。

alt 字段

每个对象还可以包含一个 alt 字段。如果 Blockly 不识别对象的 type,则会改用 alt 对象。例如,如果向 Blockly 添加了名为 field_time 的新字段,则使用此字段的块可以使用 alt 为较低版本的 Blockly 定义 field_input 回退:

JSON

{
  "message0": "sound alarm at %1",
  "args0": [
    {
      "type": "field_time",
      "name": "TEMPO",
      "hour": 9,
      "minutes": 0,
      "alt":
        {
          "type": "field_input",
          "name": "TEMPOTEXT",
          "text": "9:00"
        }
    }
  ]
}

alt 对象可以有自己的 alt 对象,因此可以进行链接。最终,如果 Blockly 无法在 args0 数组中创建对象(在尝试任何 alt 对象后),则会直接跳过该对象。