In this document, we'll discuss how to use JSON to define the inputs, fields (including labels), and connections in your block. If you're not familiar with these terms, see Anatomy of a block before proceeding.
You can also define your inputs, fields, and connections in JavaScript.
Overview
In JSON, you describe a block's structure with one or more message strings
(message0
, message1
, ...) and their corresponding argument arrays (args0
,
args1
, ...). Message strings consist of text, which is converted to labels,
and interpolation tokens (%1
, %2
, ...), which mark the locations of
connections and non-label fields. The argument arrays describe how to handle the
interpolation tokens.
For example, this block:
is defined by the following JSON:
JSON
{
"message0": "set %1 to %2",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "item",
"variableTypes": [""]
},
{
"type": "input_value",
"name": "VALUE"
}
]
}
The first interpolation token (%1
) represents a variable
field
(type: "field_variable"
). It is described by the first object in the args0
array. The second token (%2
) represents the input connection at the end of a
value input
(type: "input_value"
). It is described by the second object in the args0
array.
Messages and inputs
When an interpolation token marks a connection, it is really marking the end of the input that contains the connection. This is because the connections in value and statement inputs are rendered at the end of the input. The input contains all of the fields (including labels) after the previous input and up to the current token. The following sections show sample messages and the inputs that are created from them.
Example 1
JSON
{
"message0": "set %1 to %2",
"args0": [
{"type": "field_variable", ...} // token %1
{"type": "input_value", ...} // token %2
],
}
This creates a single value input with three fields: a label ("set"
), a
variable field, and another label ("to"
).
Example 2
JSON
{
"message0": "%1 + %2",
"args0": [
{"type": "input_value", ...} // token %1
{"type": "input_value", ...} // token %2
],
}
This creates two value inputs. The first has no fields and the second has one
field ("+"
).
Example 3
JSON
{
"message0": "%1 + %2 %3",
"args0": [
{"type": "input_value", ...} // token %1
{"type": "input_end_row", ...} // token %2
{"type": "input_value", ...} // token %3
],
}
This creates:
- A value input with no fields,
- An end-of-row input
with a label field (
"+"
), which causes the following value input to be rendered on a new row, and - A value input with no fields.
Dummy input at end of message
If your message
string ends with text or fields, you don't need to add an
interpolation token for the dummy input that contains them -- Blockly adds it
for you. For example, instead of defining a lists_isEmpty
block like this:
JSON
{
"message0": "%1 is empty %2",
"args0": [
{"type": "input_value", ...} // token %1
{"type": "input_dummy", ...} // token %2
],
}
you can let Blockly add the dummy input and define it like this:
JSON
{
"message0": "%1 is empty",
"args0": [
{"type": "input_value", ...} // token %1
],
}
The automatic addition of a tailing dummy input allows translators to change
message
without needing to modify the arguments that describe the
interpolation tokens. For more information, see Interpolation token
order.
implicitAlign
In rare cases the automatically created trailing dummy input needs to be aligned
to the "RIGHT"
or "CENTRE"
. The default if not specified is "LEFT"
.
In the example below message0
is "send email to %1 subject %2 secure %3"
and Blockly automatically adds a dummy input for the third row. Setting
implicitAlign0
to "RIGHT"
forces this row to be right aligned.
implicitAlign
applies to all inputs that are not explicitly defined in the JSON
block definition, including end-of-row inputs that replace newline characters
('\n'
). There is also the deprecated property
lastDummyAlign0
that has the same behavior as implicitAlign0
.
When designing blocks for RTL (Arabic and Hebrew), left and right are reversed.
Thus "RIGHT"
would align fields to the left.
Multiple messages
Some blocks are naturally divided into two or more separate parts. Consider this repeat block which has two rows:
If this block were described with a single message, the message0
property
would be "repeat %1 times %2 do %3"
, where %2
represents an end-of-row
input. This string is awkward for a translator because
it is difficult to explain what the %2
substitution means. The %2
end-of-row
input may also not even be desired in some languages. And there may be multiple
blocks that wish to share the text of the second row. A better approach
is to use more than one message
and args
properties:
JSON
{
"message0": "repeat %1 times",
"args0": [
{"type": "input_value", ...} // token %1 in message0
],
"message1": "do %1",
"args1": [
{"type": "input_statement", ...} // token %1 in message1
],
}
Any number of message
, args
, and implicitAlign
properties may be defined
in the JSON format, starting with 0 and incrementing sequentially. Note that the
Block Factory is not capable of splitting messages into multiple parts, but
doing so manually is straightforward.
Interpolation token order
When localizing blocks, you might need to change the order of the interpolation
tokens in a message. This is particularly important in languages that have a
different word order than English. For example, we started with a block defined
by the message "set %1 to %2"
:
Now consider a hypothetical language where "set %1 to %2"
needs to be reversed
to say "put %2 in %1"
. Changing the message (including the order of the
interpolation tokens) and leaving the arguments array unchanged results in the
following block:
Blockly automatically changed the order of the fields, created a dummy input, and switched from external to internal inputs.
The ability to change the order of the interpolation tokens in a message makes localization easier. For more information, see JSON message interpolation.
Text handling
Text on either side of an interpolation token is whitespace-trimmed.
Text using the character %
(e.g. when referring to a percentage) should use
%%
so that it is not interpreted as an interpolation token.
Blockly also automatically replaces any newline character (\n
) in the message
string with an end-of-row input.
JSON
{
"message0": "set %1\nto %2",
"args0": [
{"type": "field_variable", ...}, // token %1
{"type": "input_value", ...}, // token %2
]
}
Arguments arrays
Each message string is paired with an args
array of the same number. For
example, message0
goes with args0
. The interpolation tokens
(%1
, %2
, ...) refer to the items of the args
array and must match the
args0
array completely: no duplicates, no omissions. Token numbers refer to
the order of the items in the arguments array; they are not required to occur
in order in a message string.
Every object in the arguments array has a
type
string. The rest of the parameters vary depending on the type:
You can also define your own custom fields and custom inputs and pass them as args.
alt fields
Every object may also have an alt
field. In the case that Blockly does not
recognize the object's type
, then the alt
object is used in its place. For
example, if a new field named field_time
is added to Blockly, blocks using
this field could use alt
to define a field_input
fallback for older versions
of Blockly:
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"
}
}
]
}
An alt
object may have its own alt
object, thus allowing for chaining.
Ultimately, if Blockly cannot create an object in the args0
array (after
attempting any alt
objects) then that object is simply skipped.