En este documento, analizaremos cómo usar JSON para definir las entradas, los campos (incluidas las etiquetas) y las conexiones en tu bloque. Si no conoces estos términos, consulta Anatomía de un bloque antes de continuar.
También puedes definir tus entradas, campos y conexiones en JavaScript.
Descripción general
En JSON, describes la estructura de un bloque con una o más cadenas de mensajes (message0
, message1
, …) y sus arrays de argumentos correspondientes (args0
, args1
, …). Las cadenas de mensajes constan de texto, que se convierte en etiquetas, y tokens de interpolación (%1
, %2
, …), que marcan las ubicaciones de las conexiones y los campos que no son etiquetas. Los arrays de argumentos describen cómo controlar los tokens de interpolación.
Por ejemplo, este bloque:
se define con el siguiente código JSON:
JSON
{
"message0": "set %1 to %2",
"args0": [
{
"type": "field_variable",
"name": "VAR",
"variable": "item",
"variableTypes": [""]
},
{
"type": "input_value",
"name": "VALUE"
}
]
}
El primer token de interpolación (%1
) representa un campo de variable (type: "field_variable"
). Se describe con el primer objeto del array args0
. El segundo token (%2
) representa la conexión de entrada al final de una entrada de valor (type: "input_value"
). Se describe en el segundo objeto del array args0
.
Mensajes y entradas
Cuando un token de interpolación marca una conexión, en realidad marca el final de la entrada que contiene la conexión. Esto se debe a que las conexiones en los valores y las instrucciones de entrada se renderizan al final de la entrada. La entrada contiene todos los campos (incluidas las etiquetas) después de la entrada anterior y hasta el token actual. En las siguientes secciones, se muestran ejemplos de mensajes y las entradas que se crean a partir de ellos.
Ejemplo 1
JSON
{
"message0": "set %1 to %2",
"args0": [
{"type": "field_variable", ...} // token %1
{"type": "input_value", ...} // token %2
],
}
Esto crea una entrada de valor único con tres campos: una etiqueta ("set"
), un campo de variable y otra etiqueta ("to"
).
Ejemplo 2
JSON
{
"message0": "%1 + %2",
"args0": [
{"type": "input_value", ...} // token %1
{"type": "input_value", ...} // token %2
],
}
Esto crea dos entradas de valores. El primero no tiene campos y el segundo tiene un campo ("+"
).
Ejemplo 3
JSON
{
"message0": "%1 + %2 %3",
"args0": [
{"type": "input_value", ...} // token %1
{"type": "input_end_row", ...} // token %2
{"type": "input_value", ...} // token %3
],
}
Esto crea lo siguiente:
- Es una entrada de valor sin campos.
- Una entrada de fin de fila con un campo de etiqueta (
"+"
), que hace que la siguiente entrada de valor se renderice en una fila nueva - Es una entrada de valor sin campos.
Entrada simulada al final del mensaje
Si tu cadena message
termina con texto o campos, no es necesario que agregues un token de interpolación para la entrada ficticia que los contiene, ya que Blockly lo agrega por ti. Por ejemplo, en lugar de definir un bloque lists_isEmpty
de esta manera:
JSON
{
"message0": "%1 is empty %2",
"args0": [
{"type": "input_value", ...} // token %1
{"type": "input_dummy", ...} // token %2
],
}
puedes permitir que Blockly agregue la entrada ficticia y la defina de la siguiente manera:
JSON
{
"message0": "%1 is empty",
"args0": [
{"type": "input_value", ...} // token %1
],
}
La adición automática de una entrada ficticia final permite a los traductores cambiar message
sin necesidad de modificar los argumentos que describen los tokens de interpolación. Para obtener más información, consulta Orden de los tokens de interpolación.
implicitAlign
En casos excepcionales, la entrada ficticia final creada automáticamente debe alinearse con "RIGHT"
o "CENTRE"
. El valor predeterminado si no se especifica es "LEFT"
.
En el siguiente ejemplo, message0
es "send email to %1 subject %2 secure %3"
y Blockly agrega automáticamente una entrada ficticia para la tercera fila. Si se establece implicitAlign0
en "RIGHT"
, esta fila se alinea a la derecha.
implicitAlign
se aplica a todas las entradas que no se definen de forma explícita en la definición del bloque JSON, incluidas las entradas de fin de fila que reemplazan los caracteres de nueva línea ('\n'
). También existe la propiedad lastDummyAlign0
, que está obsoleta y tiene el mismo comportamiento que implicitAlign0
.
Cuando diseñes bloques para RTL (árabe y hebreo), se invertirán la izquierda y la derecha.
Por lo tanto, "RIGHT"
alinearía los campos a la izquierda.
Varios mensajes
Algunos bloques se dividen naturalmente en dos o más partes separadas. Considera este bloque de repetición que tiene dos filas:
Si este bloque se describiera con un solo mensaje, la propiedad message0
sería "repeat %1 times %2 do %3"
, donde %2
representa una entrada de fin de fila. Esta cadena es difícil de traducir porque es difícil explicar qué significa la sustitución %2
. Es posible que la entrada %2
de fin de fila ni siquiera sea deseable en algunos idiomas. Además, puede haber varios bloques que deseen compartir el texto de la segunda fila. Un mejor enfoque es usar más de una propiedad message
y args
:
JSON
{
"message0": "repeat %1 times",
"args0": [
{"type": "input_value", ...} // token %1 in message0
],
"message1": "do %1",
"args1": [
{"type": "input_statement", ...} // token %1 in message1
],
}
Se puede definir cualquier cantidad de propiedades message
, args
y implicitAlign
en el formato JSON, comenzando con 0 y aumentando de forma secuencial. Ten en cuenta que Block Factory no puede dividir mensajes en varias partes, pero hacerlo de forma manual es sencillo.
Orden de los tokens de interpolación
Cuando localices bloques, es posible que debas cambiar el orden de los tokens de interpolación en un mensaje. Esto es especialmente importante en idiomas que tienen un orden de palabras diferente al inglés. Por ejemplo, comenzamos con un bloque definido por el mensaje "set %1 to %2"
:
Ahora considera un idioma hipotético en el que "set %1 to %2"
debe invertirse para decir "put %2 in %1"
. Si cambias el mensaje (incluido el orden de los tokens de interpolación) y dejas sin cambios el array de argumentos, se generará el siguiente bloque:
Blockly cambió automáticamente el orden de los campos, creó una entrada ficticia y cambió de entradas externas a internas.
La capacidad de cambiar el orden de los tokens de interpolación en un mensaje facilita la localización. Para obtener más información, consulta Interpolación de mensajes JSON.
Manejo de texto
El texto a ambos lados de un token de interpolación se recorta con espacios en blanco.
El texto que usa el carácter %
(p.ej., cuando se hace referencia a un porcentaje) debe usar %%
para que no se interprete como un token de interpolación.
Blockly también reemplaza automáticamente cualquier carácter de salto de línea (\n
) en la cadena de mensaje por una entrada de fin de fila.
JSON
{
"message0": "set %1\nto %2",
"args0": [
{"type": "field_variable", ...}, // token %1
{"type": "input_value", ...}, // token %2
]
}
Arrays de argumentos
Cada cadena de mensaje se vincula con un array args
de la misma cantidad. Por ejemplo, message0
va con args0
. Los tokens de interpolación (%1
, %2
, …) hacen referencia a los elementos del array args
y deben coincidir completamente con el array args0
: no deben haber duplicados ni omisiones. Los números de token hacen referencia al orden de los elementos en el array de argumentos; no es necesario que aparezcan en orden en una cadena de mensaje.
Cada objeto del array de argumentos tiene una cadena type
. El resto de los parámetros varían según el tipo:
También puedes definir tus propios campos personalizados y entradas personalizadas, y pasarlos como argumentos.
Campos alternativos
Cada objeto también puede tener un campo alt
. En el caso de que Blockly no reconozca el type
del objeto, se usará el objeto alt
en su lugar. Por ejemplo, si se agrega un campo nuevo llamado field_time
a Blockly, los bloques que usen este campo podrían usar alt
para definir una alternativa field_input
para versiones anteriores de 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"
}
}
]
}
Un objeto alt
puede tener su propio objeto alt
, lo que permite el encadenamiento.
En última instancia, si Blockly no puede crear un objeto en el array args0
(después de intentar crear cualquier objeto alt
), simplemente se omite ese objeto.