Add Custom Blocks

While Blockly defines a number of standard blocks, most applications need to define and implement at least a few domain relevant blocks.

Blocks are composed of three components:

  • Block definition object: Defines the look and behaviour of a block, including the text, colour, fields, and connections.
  • Toolbox reference: A reference to the block type in the toolbox XML, so users can add it to the workspace.
  • Generator function: Generates the code string for this block. It is always written in JavaScript, even if the target language is not JavaScript.

Block Definition

Blockly for web loads Blocks via script files. The blocks/ directory includes several such examples for the standard blocks. Assuming your blocks don't fit in the existing categories, create a new JavaScript file. This new JavaScript file needs to be included in the list of <script ...> tags in the editor's HTML file.

A typical block definition looks like this:

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: This is the type name of the block. Since all blocks share the same namespace, it is good to use a name made up of your category (in this case string) followed by your block's function (in this case length).

  • init: This function defines the look and feel of the block.

This defines the following block:

A `string_length` block.

The details of block definitions can be found in Define Blocks.

JSON Array

Multiple blocks can be defined at once by using an array of JSON block definitions.

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}"
  }
]);

Add Toolbox Reference

Once defined, use the type name to reference the block to the toolbox:

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

See the Toolbox guide for more details.

Add block-code generator

Finally, to transform the block into code, pair the block with a generator function. Generators are specific to the desired output language, but standard generators generally take the following format:

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];
};

The generator function takes a reference to the block for processing. It renders the inputs (the VALUE input, above) into code strings, and then concatenates those into a larger expression.

→ More info on block-code generators...