Extend the Editor Toolbar¶
In this tutorial, you’ll learn how to extend the SmallBlock CMS editor toolbar by adding a custom button. Toolbar extensions allow developers to introduce editor-facing tools — such as inserting snippets, shortcodes, or formatted text — without altering the CMS core.
You will create a simple “Insert Quote” button that adds a canned sentence wherever the editor’s cursor is located.
—
Before You Begin¶
You should have:
A working SmallBlock CMS site (from Build Your First Site).
Completed the Create a Plugin tutorial.
Basic JavaScript familiarity.
Access to your project’s plugin directory.
This tutorial assumes the plugin you created earlier is located in:
plugins/quote_of_the_day/
—
How Toolbar Extensions Work¶
SmallBlock exposes a global JavaScript interface named
SmallBlock.Toolbar that allows plugins to register new buttons.
A toolbar extension includes:
A JavaScript file containing registration code
(Optional) a stylesheet to customize button appearance
A registration entry in
plugin.py
The diagram below illustrates the client-side extension flow:
![digraph G {
rankdir=LR;
node [shape=box, style="rounded,filled", fillcolor="#eef3f8"];
A [label="Static JS File\n(toolbar-quote.js)"];
B [label="SmallBlock.Toolbar.registerButton()"];
C [label="CMS Editor UI"];
D [label="User Clicks Button"];
E [label="Editor Inserts Text"];
A -> B -> C -> D -> E;
}](../_images/graphviz-a18ee9ad7c1bc6955fc4e84a3ac763a67f76ce46.png)
—
Step 1 — Create a Static Asset Directory¶
Inside your plugin folder, create directories for JavaScript and CSS assets:
cd mysite/plugins/quote_of_the_day
mkdir -p static/js
mkdir -p static/css
Verify
Your plugin directory should now contain:
quote_of_the_day/
├── plugin.py
├── __init__.py
└── static/
├── js/
└── css/
—
Step 2 — Add the JavaScript Toolbar Extension¶
Create static/js/toolbar-quote.js:
(function () {
// Wait for the CMS runtime
if (!window.SmallBlock || !SmallBlock.Toolbar) {
console.warn("SmallBlock.Toolbar not available.");
return;
}
SmallBlock.Toolbar.registerButton({
id: "insert-quote",
label: "Insert Quote",
icon: "💬",
tooltip: "Insert Quote of the Day",
onClick: function (editor) {
const quote =
"“The only way to do great work is to love what you do.” — Steve Jobs";
editor.insertText(quote);
},
});
console.log("Toolbar extension: Insert Quote loaded.");
})();
Explanation
registerButton()adds a button to the editor toolbar.editor.insertText()inserts content at the user’s cursor.
Verify
Check the browser console while loading the editor UI:
You should see:
Toolbar extension: Insert Quote loaded.
—
Step 3 — Register the Static Files¶
Add the JS file to your plugin registration in plugin.py:
def register(app):
app.add_static("quote_of_the_day/js/toolbar-quote.js")
app.logger.info("Toolbar extension registered.")
Restart the development server:
smallblock runserver
Verify
Open your browser’s developer tools → Network tab. You should see the file:
/static/quote_of_the_day/js/toolbar-quote.js
—
Step 4 — Add Optional Styling¶
Create static/css/toolbar-quote.css:
.sb-toolbar-button#insert-quote {
background-color: #16364b;
color: #e6edf3;
border-radius: 6px;
padding: 0.25rem 0.5rem;
transition: background-color 0.2s ease-in-out;
}
.sb-toolbar-button#insert-quote:hover {
background-color: #23445a;
}
Then update your plugin registration:
def register(app):
app.add_static("quote_of_the_day/js/toolbar-quote.js")
app.add_static("quote_of_the_day/css/toolbar-quote.css")
app.logger.info("Toolbar extension registered.")
—
Troubleshooting¶
The button doesn’t appear
Ensure the JS file is being loaded:
curl -I http://127.0.0.1:8000/static/quote_of_the_day/js/toolbar-quote.js
Confirm the plugin is enabled in your configuration.
Check the browser console for JavaScript errors.
Button appears, but clicking does nothing
The editor instance may not be available; check for errors in:
SmallBlock.Toolbar.registerButton
Styles not applying
Make sure the CSS file path is correct.
Inspect the element — another rule may be overriding your styles.
—
Next Steps¶
Continue building interactive and dynamic features with:
Using Template Tags — pass dynamic data to templates.
Create a Plugin — reuse plugin assets and logic.
Building a Custom Theme — integrate toolbar styles into site themes.