Agregar bloques personalizados

Si bien Blockly define una cantidad de bloques estándar, la mayoría de las aplicaciones deben definir e implementar al menos algunos bloques relevantes para el dominio.

Los bloques constan de tres componentes:

  • Objeto de definición del bloque: define el aspecto y el comportamiento de un bloque, incluidos el texto, el color, los campos y las conexiones.
  • Referencia de la caja de herramientas: Es una referencia al tipo de bloque en el XML de la caja de herramientas para que los usuarios puedan agregarlo al lugar de trabajo.
  • Función de generador: genera la cadena de código para este bloque. Siempre está escrito en JavaScript, incluso si el idioma objetivo no es JavaScript.

Definición del bloqueo

Blockly para la Web carga Blocks a través de archivos de secuencias de comandos. El directorio blocks/ incluye varios ejemplos de este tipo para los bloques estándar. Si tus bloques no se ajustan a las categorías existentes, crea un nuevo archivo JavaScript. Este nuevo archivo JavaScript debe incluirse en la lista de etiquetas <script ...> del archivo HTML del editor.

Una definición de bloque típica se ve de la siguiente manera:

JSON

Blockly.Blocks['string_length'] = {
  init: function() {
    this.jsonInit({
      "message0": 'length of %1',
      "args0": [
        {
          "type": "input_value",
          "name": "VALUE",
          "check": "String"
        }
      ],
      "output": "Number",
      "colour": 160,
      "tooltip": "Returns number of letters in the provided text.",
      "helpUrl": "http://www.w3schools.com/jsref/jsref_length_string.asp"
    });
  }
};

JavaScript

Blockly.Blocks['string_length'] = {
  init: function() {
    this.appendValueInput('VALUE')
        .setCheck('String')
        .appendField('length of');
    this.setOutput(true, 'Number');
    this.setColour(160);
    this.setTooltip('Returns number of letters in the provided text.');
    this.setHelpUrl('http://www.w3schools.com/jsref/jsref_length_string.asp');
  }
};
  • string_length: Es el nombre del tipo del bloque. Como todos los bloques comparten el mismo espacio de nombres, conviene usar un nombre compuesto por tu categoría (en este caso, string) seguido de la función del bloque (en este caso, length).

  • init: Esta función define la apariencia del bloque.

Esto define el siguiente bloque:

Un bloque `string_length`.

Puedes encontrar los detalles de las definiciones de bloques en Cómo definir bloques.

Array JSON

Se pueden definir varios bloques a la vez mediante un array de definiciones de bloques JSON.

JSON

Blockly.defineBlocksWithJsonArray([
  // Block for colour picker.
  {
    "type": "colour_picker",
    "message0": "%1",
    "args0": [
      {
        "type": "field_colour",
        "name": "COLOUR",
        "colour": "#ff0000"
      }
    ],
    "output": "Colour",
    "helpUrl": "%{BKY_COLOUR_PICKER_HELPURL}",
    "style": "colour_blocks",
    "tooltip": "%{BKY_COLOUR_PICKER_TOOLTIP}",
    "extensions": ["parent_tooltip_when_inline"]
  },
  // Block for random colour.
  {
    "type": "colour_random",
    "message0": "%{BKY_COLOUR_RANDOM_TITLE}",
    "output": "Colour",
    "helpUrl": "%{BKY_COLOUR_RANDOM_HELPURL}",
    "style": "colour_blocks",
    "tooltip": "%{BKY_COLOUR_RANDOM_TOOLTIP}"
  }
]);

Agregar referencia de Toolbox

Una vez definido, usa el nombre del tipo para hacer referencia al bloque a la caja de herramientas:

<xml id="toolbox" style="display: none">
  <category name="Text">
    <block type="string_length"></block>
  </category>
  ...
</xml>

Consulta la guía de la Caja de herramientas para obtener más detalles.

Agrega un generador de códigos de bloque

Por último, para transformar el bloque en código, vincúlalo con una función de generador. Los generadores son específicos para el lenguaje de salida deseado, pero los generadores estándar suelen adoptar el siguiente formato:

javascriptGenerator.forBlock['text_length'] = function(block, generator) {
  // String or array length.
  var argument0 = generator.valueToCode(block, 'VALUE', Order.FUNCTION_CALL) || '\'\'';
  return [argument0 + '.length', Order.MEMBER];
};

La función de generador toma una referencia al bloque para su procesamiento. Renderiza las entradas (la entrada VALUE, anterior) en strings de código y, luego, las concatena en una expresión más grande.

→ Más información sobre generadores de código de bloque...