썸머노트는 위지윅으로 코드 몇줄만 붙여오면 내 게시판에 에디터를 추가할 수 있는 아주 유용한 오픈소스다.
특히 사용자가 원하는대로 기능을 추가하는 것도 간편하다.
먼저 적용할 수 있는 기술은 styleTags이다.
styleTags 프로퍼티는 사용자가 지정한 태그를 바로 적용할 수 있게 도와주는 기능이다.
//# summerNote
$('.summernote').summernote({
toolbar: [
['style', ['borderBtn', 'style']],
['font', ['bold', 'underline', 'clear']],
['fontsize', ['fontsize']],
['height', ['height']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']],
['insert', ['link']],
['view', ['fullscreen', 'codeview', 'help']],
['image', ['picture', 'resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],
['float', ['floatLeft', 'floatRight', 'floatNone']],
['remove', ['removeMedia']],
],
styleTags: [
{
title: '제목',
tag: 'h1',
className: 'titleFont',
value: 'h1'
},
{
title: '일반(숫자)',
tag: 'p',
className: 'normalFont',
value: 'p'
},
{
title: '서브',
tag: 'p',
className: 'subFont',
value: 'p'
},
],
buttons: {
borderBtn: borderBtn,
},
height: 350,
lang: 'ko-KR',
lineHeights: ['0.2', '0.3', '0.4', '0.5', '0.6', '0.8', '1.0', '1.2', '1.4', '1.5', '2.0', '3.0'],
callbacks: {
onImageUpload: function(files){
uploadSummernoteImageFile(files[0], this, 'community');
},
onPaste: function (e) {
var clipboardData = e.originalEvent.clipboardData;
if (clipboardData && clipboardData.items && clipboardData.items.length) {
var item = clipboardData.items[0];
if (item.kind === 'file' && item.type.indexOf('image/') !== -1) {
e.preventDefault();
}
}
}
}
})
사진처럼 해당 태그가 출력되는걸 볼수 있다.
다만 이렇게 styleTags를 사용하는 방법은 p, pre, h1, h2 등과 같이 태그 자체를 출력해주기 때문에 p태그 안에 인라인 style을 적용하는 방법 등은 제한이 된다.
물론 className을 지정해서 별도의 css를 쓸 수 있지만, 현재 상황은 관리자 모드에서 작성한 글을 클라이언트 화면에 보여지도록 하고 있다.
관리자 환경에선 부트스트랩을 사용하며, 프론트는 리액트를 쓰고 있다.
이 두 차이로 인해 최대한 썸머노트에 저장된 html코드를 건드리지 않고 전달하는 inline style을 사용하고 싶다.
위에 올린 summernote 코드 중간에 "buttons" 란 이름으로 프로퍼티가 들어간게 보인다. 이걸 활용한다.
buttons: {
borderBtn: borderBtn,
},
또한, summernote의 툴바가 인식할 수 있도록 toolbar에도 방금 작성한 borderBtn을 써준다.
['style', ['borderBtn', 'style']],
그리고 아래 함수를 작성해주면 된다.
var borderBtn = function() {
var ui = $.summernote.ui;
var button = ui.button({
contents: '<i class="fa fa-pencil"/> 테두리',
tooltip: '테두리 생성',
click: function() {
const selection = window.getSelection();
const newRange = selection.getRangeAt(0);
let node = document.createElement('span');
selection.addRange(newRange);
node.innerHTML = '<p style="border:1px solid #f1a417; text-align: center; padding: 40px 0 40px 0;"> 내용 </p>';
node.innerHTML += '<br><br>';
newRange.deleteContents();
newRange.insertNode(node);
}
});
return button.render();
}
이 함수가 동작하는 것은 click 메소드 부터인데, 버튼을 클릭하는 순간 실행된다.
내용은 selection이라는 이름으로 커서 위치를 가져오고, 새 커서 위치를 저장.
사용자가 원하는 위치에 커서를 놓으면 그곳에 테두리를 생성하게 된다. (엄밀히 따지면, 생성보다는 innerHTML로 인해 내용이 입력되는 것이라 할 수 있다.)
그럼 사진 맨 위 상단에 "테두리"라는 버튼이 생성되었고, 이것을 누르면 textarea에 테두리가 생긴다.
이렇게 원하는 태그를 넣을 수 있다.
.