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 @@ -3,6 +3,8 @@ pagination_prev: null
description: Overview of the "Customizing your themes" codelab.
---

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

# Customizing your themes

## 1. Codelab overview
Expand All @@ -17,12 +19,27 @@ In this codelab you will learn how to:

### What you'll build

A very simple Blockly workspace with customized themes.
You'll start from the Blockly sample app and give it a custom "Halloween" theme,
customizing the colours of the workspace components, the toolbox categories, and
the blocks themselves.

<Image
src="/images/codelabs/theme-extension/block_styles.png"
alt="A Blockly workspace with a custom orange and purple Halloween theme."
className="codelabImage"
/>

The code samples are written in ES6 syntax. You can find the code for the
[completed theme codelab](https://github.com/RaspberryPiFoundation/blockly/tree/main/packages/docs/docs/codelabs/theme-extension-identifier/complete-code)
on GitHub.

### What you'll need

- A browser
- 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.

This codelab is focused on Blockly's theme extension. Non-relevant concepts
are glossed over and provided for you to simple copy and paste.
are glossed over and 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 your themes](../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.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "custom-theme-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 2026 Raspberry Pi Foundation
* 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