The first plugin

We will build a Simple Image plugin that allows us to add images to our articles. You can view the final result of the plugin.

Preparation a playground

At first we need to create some files when we will develop and test our new Tool. Create a folder with these three files:

/simple-image ├╴ simple-image.js ├╴ simple-image.css └╴ example.html

In example.html we will test our plugin, so lets add some markup and connect Editor.js there:

<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script> <script src="simple-image.js"></script> <link href="simple-image.css" rel="stylesheet"/> <div id="editorjs"></div> <script> const editor = new EditorJS({ autofocus: true }); </script>

If you open this page in browser, you'll see an empty Editor with only internal Paragraph Tool available. Now we a ready to start creating own plugin.

Render and Save

Ok, let's get started with creation a JavaScript class for our Tool in simple-image.js file.

class SimpleImage { }

We need at least of two methods to create a Block Tool for Editor.js — render and save.

First method, render, will create an UI of a Block that will be appended when our Tool will be selected from the Toolbox. Second method, save — will extract the Block's data from that UI.

Our UI will be a quite simple: just an input in which users will paste image URL. So let's implement a render method:

class SimpleImage { render(){ return document.createElement('input'); } }

Then we need to provide a save method for extracting a Block data from the UI:

class SimpleImage { render(){ return document.createElement('input'); } save(blockContent){ return { url: blockContent.value } } }

On saving, Editor.js will pass Block's content to the save method and we should implement a logic of which data we should save by our Tool. Block content is the Element returned by render with actual state of that.

So in our case, we just need to get input's value and return our Tool's data object:

{ url: '//pasted-image-url.png' }

We will add a «caption» and other fields to our Block later.

Showing at the Toolbox

Our Block Plugin is almost done. To make that appear at the Toolbox, we should provide an icon and a title with a static getter toolbox.

class SimpleImage { static get toolbox() { return { title: 'Image', icon: '<svg version="1" xmlns="http://www.w3.org/2000/svg" width="85" height="85"><path d="M71 12H14C6 12 0 17 0 25v35c0 7 6 13 14 13h57c8 0 14-6 14-13V25c0-8-6-13-14-13zm5 39L63 35l-3-2-4 2-13 16-5-3-3-1-3 2-10 16h-8c-3 0-5-2-5-5V25c0-3 2-5 5-5h57c3 0 5 2 5 5v26zM24 27c-4 0-7 3-7 7s3 7 7 7c5 0 8-3 8-7s-3-7-8-7z"/></svg>' }; } render(){ return document.createElement('input'); } save(blockContent){ return { url: blockContent.value } } }

Our Tool is ready. It's time to connect it with Editor.

Connecting to the Editor

Let's add a tools property to the configuration object at the example.html.

<script> const editor = new EditorJS({ autofocus: true, tools: { image: SimpleImage } }); </script>

Open example.html in a browser: if everything is fine, you will see a Plus Button of a Toolbox. Press Tab or click on the Plus Button and our Tool will be there.

Our new Tool is ready to use. Icon and title got from the toolbox getter.
Our new Tool is ready to use. Icon and title got from the toolbox getter.

After you select an Image Tool, the render will be called and returned input will be placed as a new Block. You can add some CSS classes to it and place styles at simple-image.css file.

Testing a save method

To final test we need to check how saving method works. Add a Save-button and output-zone to the example.html

<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script> <script src="simple-image.js"></script> <link href="simple-image.css" rel="stylesheet"/> <div id="editorjs"></div> <button id="save-button">Save</button> <pre id="output"></pre> <script> const editor = new EditorJS({ autofocus: true, tools: { image: SimpleImage } }); const saveButton = document.getElementById('save-button'); const output = document.getElementById('output'); saveButton.addEventListener('click', () => { editor.save().then( savedData => { output.innerHTML = JSON.stringify(savedData, null, 4); }) }) </script>

Now everything is ready. You can add Image Block at Editor, paste image URL and click on the Save button. In output zone you will see saved Editor.js data:

{ "time": 1552744582955, "blocks": [ { "type": "image", "data": { "url": "https://cdn.pixabay.com/photo/2017/09/01/21/53/blue-2705642_1280.jpg" } } ], "version": "2.11.10" }

We have create some preparations stuff for our playground, but actually all you need to create a Block Tool plugin is the simplest save and render methods. If you want to put your Tool in Toolbox, static getter toolbox with icon and title allows to do that. 

In the next chapter we learn how to show previously saved data of our tool.