extension , addon / plugin 만들기 / editorjs plugin / wyswyg editor / block style editor / editorjs extention / editorjs plugin
Editor.js 의 Block tool 만들기
Block tool 은 다양한 기능을 하게 만들 수 있다. 여기서는 가장 기본적인 내용만 정리했다. 자세한 내용은 ref. 1을 확인하자.
그래서 Block tool 은 2가지 경우를 처리한다.
- 원하는 type 으로 값을 입력하도록 정해졌을 때,
- 그것에 대한 입력화면(
render
)- 여기서 input 에 event handler 등을 설정해 놓을 수 있다.
- 예를 들어 image plugin 경우에 paste event 가 발생하면, 그 url 에 대한 image tag 를 만들게 하는 등의 작업을 하도록 할 수 있다.
- 또는, 추가로 입력받는 곳을 보여주는 등의 작업.
- 입력된 값을 data 로 추출될때 어떤 format 으로 만들것인지 결정(
save
)
- 그것에 대한 입력화면(
- 특정 type 으로 된 값이 들어올때 어떻게 처리할지.
- type 이 정해지지 않은 값이 paste 될 때, 그 값의 패턴을 보고 특정 작업을 하도록 할 수도 있다.
다시말하면, 해당 block을 특정 type 으로 처리할 수 있게 해준다고 보면 될 것 같다.
다음처럼 BlockTool 을 만들면, EditorJS 로 연결하게 된다. 이때 이 BlockTool 이 어떤 type 을 처리할 지를 정하게 된다. 아래 코드를 보면 MyBlockTool 은 type image100
으로 들어오는 값을 처리하게 되는 것이다.
const editor = new EditorJS({
autofocus: true,
tools: {
// 여기의 `image` 가 type 이 된다.
image100: MyBlockTool
}
});
예를 들면, 다음과 같은 모습의 data 를 만들어주게 된다.
{
"time": 1691648520461,
"blocks": [
{
"id": "kuuLDGZNXn",
"type": "image100", // <-- image100 type
"data": {
"url": "wtew"
}
}
],
"version": "2.27.2"
}
입력 부분
- Editor.js 의 Block tool 예시 : GitHub - editor-js/simple-image-tutorial | Block Tool
기본적인 구조는 다음과 같다. render
와 save
는 필수이다.
render
함수는 Toolbox 에서 선택됐을 때의 UI 를 그려준다.save
함수는 block 에서 data 를 추출하는 역할을 한다.- Toolbox(메뉴) 에 보이게 하려면
static get toolbox
도 구현해야 한다.- 참고, Toolbox 는 그림에서 ‘+’ 기호를 누를 때 나오는 메뉴를 이야기한다.
class MyBlockTool {
// 메뉴(Toolbox)에 보이는 내용
static get toolbox() {
return {
title: 'Image',
// icon: '<svg width="17" height="15" viewBox="0 0 336 276" xmlns="http://www.w3.org/2000/svg"><path d="M291 150V79c0-19-15-34-34-34H79c-19 0-34 15-34 34v42l67-44 81 72 56-29 42 30zm0 52l-43-30-56 30-81-67-66 39v23c0 19 15 34 34 34h178c17 0 31-13 34-29zM79 0h178c44 0 79 35 79 79v118c0 44-35 79-79 79H79c-44 0-79-35-79-79V79C0 35 35 0 79 0z"/></svg>'
};
}
// 메뉴(Toolbox)에서 해당 tool을 선택해서 실행할 때 보이는 UI
render(){
return document.createElement('input');
}
save(blockContent){
return {
url: blockContent.value
}
}
validate(savedData){
if (!savedData.url.trim()){
return false;
}
return true;
}
}
Editor.js 와 연결
위에서 만든 BockTool 을 연결하려면 아래처럼 해주면 된다. 그러면 이제 화면의 메뉴에서 보인다.
const editor = new EditorJS({
autofocus: true,
tools: {
// 여기의 `image` 가 type 이 된다.
image: MyBlockTool
}
});
그림처럼 toolbox
에서 정의한 내용이 menu 에 보여진다.
full code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<script src="https://cdn.jsdelivr.net/npm/@editorjs/editorjs@latest"></script>
<script type="text/javascript">
class MyBlockTool {
constructor({
data
}) {
this.data = data;
}
static get toolbox() {
return {
title: 'Image',
icon: '<svg width="17" height="15" viewBox="0 0 336 276" xmlns="http://www.w3.org/2000/svg"><path d="M291 150V79c0-19-15-34-34-34H79c-19 0-34 15-34 34v42l67-44 81 72 56-29 42 30zm0 52l-43-30-56 30-81-67-66 39v23c0 19 15 34 34 34h178c17 0 31-13 34-29zM79 0h178c44 0 79 35 79 79v118c0 44-35 79-79 79H79c-44 0-79-35-79-79V79C0 35 35 0 79 0z"/></svg>'
};
}
render() {
this.wrapper = document.createElement('div');
const input = document.createElement('input');
this.wrapper.classList.add('simple-image');
this.wrapper.appendChild(input);
input.placeholder = 'Paste an image URL...';
input.value = this.data && this.data.url ? this.data.url : '';
input.addEventListener('paste', (event) => {
this._createImage(event.clipboardData.getData('text'));
});
return this.wrapper;
}
_createImage(url) {
const image = document.createElement('img');
const caption = document.createElement('input');
image.src = url;
caption.placeholder = 'Caption...';
this.wrapper.innerHTML = '';
this.wrapper.appendChild(image);
this.wrapper.appendChild(caption);
}
save(blockContent) {
return {
url: blockContent.value
}
}
validate(savedData) {
// if (!savedData.url.trim()) {
// return false;
// }
return true;
}
}
</script>
<style type="text/css">
.simple-image {
padding: 20px 0;
}
.simple-image input {
width: 100%;
padding: 10px;
border: 1px solid #e4e4e4;
border-radius: 3px;
outline: none;
font-size: 14px;
}
</style>
</head>
<body>
<div id="editorjs"></div>
<button id="save-button">Save</button>
<pre id="output"></pre>
<script>
const editor = new EditorJS({
// logLevel: 'VERBOSE',
autofocus: true,
tools: {
image2: MyBlockTool,
},
data: {
time: 1552744582955,
blocks: [
{
type: "image2",
data: {
url: "https://cdn.pixabay.com/photo/2017/09/01/21/53/blue-2705642_1280.jpg"
}
}
],
version: "2.11.10"
}
});
const saveButton = document.getElementById('save-button');
const output = document.getElementById('output');
saveButton.addEventListener('click', () => {
editor.save().then( savedData => {
console.log(savedData)
output.innerHTML = JSON.stringify(savedData, null, 4);
})
})
</script>
</body>
</html>
댓글 없음:
댓글 쓰기