Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ We will discuss these in detail in later sections of the codelab.

### Make a RegistryItem

Add a function to `index.js` named `registerHelloWorldItem`. Create a new registry item in your function:
Add a function to `src/index.js` named `registerHelloWorldItem`. Create a new registry item in your function:

```js
function registerHelloWorldItem() {
Expand All @@ -42,18 +42,15 @@ function registerHelloWorldItem() {
}
```

Call your function from `start`:
Call your function in `src/index.js`, before the UI element setup and `Blockly.inject` call:

```js
function start() {
registerHelloWorldItem();

Blockly.ContextMenuItems.registerCommentOptions();
// Create main workspace.
workspace = Blockly.inject('blocklyDiv', {
toolbox: toolboxSimple,
});
}
registerHelloWorldItem();

// Set up UI elements and inject Blockly
const codeDiv = document.getElementById('generatedCode').firstChild;
// ...
const ws = Blockly.inject(blocklyDiv, {toolbox});
```

### Register it
Expand All @@ -70,12 +67,20 @@ function registerHelloWorldItem() {
```

:::note
you will never need to make a new `ContextMenuRegistry`. Always use the singleton `Blockly.ContextMenuRegistry.registry`.
You will never need to make a new `ContextMenuRegistry`. Always use the singleton `Blockly.ContextMenuRegistry.registry`.
:::

### Enable comment context menus

This codelab demonstrates context menus on workspaces, blocks, and comments. Blockly registers the workspace and block options by default, but the comment options (including the **Add Comment** option you'll use to create comments while testing) must be registered separately. Add this call to `src/index.js`, before the `Blockly.inject` call:

```js
Blockly.ContextMenuItems.registerCommentOptions();
```

### Test it

Reload your web page and open a context menu on the workspace (right-click with a mouse, or press `Ctrl+Enter` (Windows) or `Command+Enter` (Mac) if you are navigating Blockly with the keyboard). You should see a new option labeled "Hello World" at the bottom of the context menu.
Refresh the running page (or run `npm start`) and open a context menu on the workspace (right-click with a mouse, or press `Ctrl+Enter` (Windows) or `Command+Enter` (Mac) if you are navigating Blockly with the keyboard). You should see a new option labeled "Hello World" at the bottom of the context menu.

<Image
src="/images/codelabs/context-menu-option/hello_world.png"
Expand Down
10 changes: 8 additions & 2 deletions packages/docs/docs/codelabs/context-menu-option/callback.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
description: How to add a callback to a context menu item.
---

import Image from '@site/src/components/Image';

# Customizing context menus

## 7. Callback
Expand All @@ -25,8 +27,12 @@ As an example, update the help item's `callback` to add a block to the workspace

### Test it

- Reload the page and open a context menu on the workspace.
- Refresh the running page and open a context menu on the workspace.
- Select the **Help** option.
- A text block should appear in the top left of the workspace.

![A text block containing the text "Now there is a block".](../../../static/images/codelabs/context-menu-option/there_is_a_block.png)
<Image
src="/images/codelabs/context-menu-option/there_is_a_block.png"
alt='A text block containing the text "Now there is a block".'
className="codelabImage"
/>
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,9 @@ A very simple Blockly workspace with a few new context menu options.
- A browser.
- A text editor.
- Basic knowledge of HTML, CSS, and JavaScript.
- node.js and npm installed ([instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)).
- Comfort using the command line/terminal.

You can find the code for the [completed context menu codelab](https://github.com/RaspberryPiFoundation/blockly/tree/main/packages/docs/docs/codelabs/context-menu-option/complete-code) on GitHub.

This codelab is focused on Blockly's context menus. Non-relevant concepts and code are glossed over and are provided for you to simply copy and paste.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Completed code

The finished code for the [Customizing context menus](../codelab-overview.mdx) codelab.

## Run it

To run the complete code, navigate to the `complete-code` folder in your terminal, then run:

```bash
npm install # downloads the libraries the app needs (one time)
npm start # opens the app at http://localhost:...
```

New to npm? See [installing node & npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "context-menu-option-codelab",
"version": "1.0.0",
"description": "A sample app using Blockly",
"main": "index.js",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack --mode production",
"start": "webpack serve --open --mode development"
},
"keywords": [
"blockly"
],
"author": "",
"license": "Apache-2.0",
"devDependencies": {
"css-loader": "^6.7.1",
"html-webpack-plugin": "^5.5.0",
"source-map-loader": "^4.0.1",
"style-loader": "^3.3.1",
"webpack": "^5.93.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4"
},
"dependencies": {
"blockly": "^13.0.0"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2026 Raspberry Pi Foundation
* SPDX-License-Identifier: Apache-2.0
*/

import * as Blockly from 'blockly/core';

// Create a custom block called 'add_text' that adds
// text to the output div on the sample app.
// This is just an example and you should replace this with your
// own custom blocks.
const addText = {
type: 'add_text',
message0: 'Add text %1',
args0: [
{
type: 'input_value',
name: 'TEXT',
check: 'String',
},
],
previousStatement: null,
nextStatement: null,
colour: 160,
tooltip: '',
helpUrl: '',
};

// Create the block definitions for the JSON-only blocks.
// This does not register their definitions with Blockly.
// This file has no side effects!
export const blocks = Blockly.common.createBlockDefinitionsFromJsonArray([
addText,
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @license
* Copyright 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import { Order } from 'blockly/javascript';

// Export all the code generators for our custom blocks,
// but don't register them with Blockly yet.
// This file has no side effects!
export const forBlock = Object.create(null);

forBlock['add_text'] = function (block, generator) {
const text = generator.valueToCode(block, 'TEXT', Order.NONE) || "''";
const addText = generator.provideFunction_(
'addText',
`function ${generator.FUNCTION_NAME_PLACEHOLDER_}(text) {

// Add text to the output area.
const outputDiv = document.getElementById('output');
const textEl = document.createElement('p');
textEl.innerText = text;
outputDiv.appendChild(textEl);
}`,
);
// Generate the function call for this block.
const code = `${addText}(${text});\n`;
return code;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
body {
margin: 0;
max-width: 100vw;
}

pre,
code {
overflow: auto;
}

#pageContainer {
display: flex;
width: 100%;
max-width: 100vw;
height: 100vh;
}

#blocklyDiv {
flex-basis: 100%;
height: 100%;
min-width: 600px;
}

#outputPane {
display: flex;
flex-direction: column;
width: 400px;
flex: 0 0 400px;
overflow: auto;
margin: 1rem;
}

#generatedCode {
height: 50%;
background-color: rgb(247, 240, 228);
}

#output {
height: 50%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>Blockly Sample App</title>
</head>
<body>
<div id="pageContainer">
<div id="outputPane">
<pre id="generatedCode"><code></code></pre>
<div id="output"></div>
</div>
<div id="blocklyDiv"></div>
</div>
</body>
</html>
Loading
Loading