블로그 프로젝트 - 2-4 : 주요 개발 내용 - WYSIWIG 에디터 Summernote

1. Summernote

1. 무엇인가?

Summernote는 Bootstrap 4 기반의 위지윅 에디터이다. 위지윅 에디터란, 에디터에서 보이는 모습을 그대로 HTML 태그를 추가하여 결과물로 보여주는 에디터이다.

2. 왜 사용했는가?

그냥 input Textarea 태그를 통해 제목 - 글을 제공하는 방법도 있었지만, 위지윅 에디터를 통해 좀 더 다채로운 모습의 글을 서비스 할 수 있도록 적용하였다. 그리고 무엇보다도 일반 input Textarea 태그만 사용하게 되면 이미지를 삽입하는 것이 사실상 불가능할 정도로 어려운 과제가 되어버린다. 따라서 위지윅 에디터를 적용하게 되었다.

3. 어떻게 사용했는가?

  1. CDN 적용
    Bootstrap 4를 위한 CDNSummernote를 위한 CDN을 적용시킨다. Summernote의 디자인 CSS는 Bootstrap 4에 의존한다.

postWrite.ejs의 Head부분

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>summernote</title>
    <!-- CDN 추가 시작 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
    <script
    src="https://code.jquery.com/jquery-3.5.1.min.js"
    integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
    crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote.min.js"></script>
    <!-- CDN 추가 부분 끝 -->
</head>
...
  1. Summernote 에디터를 적용할 부분에 textarea input 태그를 설정한다. 이 때 반드시 id요소를 설정한다.

postWrite.ejs의 Body 부분

<body>
<form method="post" action="/insertPost">
    <textarea id="summernote" name="editordata"></textarea>
    <button type="submit">등록</button>
</form>
</body>
  1. Script 태그 내부에 JQuery를 통해 초기화 시켜준다. 이 때 적용될 textarea의 id값에 유의한다.
    또한 이미지 업로드를 위해, 이미지 업로드가 될 시(onImageUpload) 동작을 지정해 준다.(sendFile())

postWrite.ejs의 script부분 (1)

<script>
// summernote init
$(function(){
  $('#summernote').summernote({ 
    placeholder: '내용',
    tabsize: 2,
    focus: true,
    callbacks:{
      // onImageUpload를 통해 이미지 업로드시 동작 개조 가능
      // 개조하지 않으면 Base64로 이미지가 전환돼서 img태그로 바뀐뒤 본문에 추가된다.
      onImageUpload: function(files){ // 이미지 업로드시
        sendFile(files[0], this); // sendFile함수 동작
      }
    }
  });
});
...
  1. JQuery의 ajax로 이미지 업로드를 하는 함수를 만들어 이미지를 AWS S3 이미지 스토리지에 저장한 후, 내용을 Editor에 삽입한다. 위 코드 부분의 onImageUpload부분 참고.
    ajax를 사용한 이유는, ajax 사용 시 웹 페이지를 갱신하지 않고도 request가 가능한데, 따라서 에디터의 내용을 새로고침으로 날리지 않고(!) 본문 내용에 이미지 삽입이 가능해진다.

postWrite.ejs의 script부분(2)

function sendFile(file, editor){
  data = new FormData()
  data.append("img", file)
  $.ajax({ // ajax사용시 웹 페이지를 갱신하지 않고도 request가 가능하다.
    data: data,
    type: "POST",
    url: "/api/insertImage", // 이미지 업로드를 위한 api url
    cache: false,
    contentType: false,
    enctype: "multipart/form-data",
    processData: false,
    success: function (response) { // 성공시 img태그 생성
      var imgurl = $('<img>').attr({
        'src': response,
        'crossorigin': 'anonymous',
        'class': 'img-fluid',
    });
      $("#summernote").summernote("insertNode", imgurl[0]); // editor 내용에 삽입
    },
  })
}
  1. ajax로 호출할 api를 만든다.

routes/api.js

...
const upload = require('../lib/multer');
const router = express.Router();
router.post('/insertImage', upload.single('img'), insertImage);
...

apiController.js

// @post
// /api/insertImage
const insertImage = async(req, res) => {
    imgurl = '';
    if(req.file !== undefined) {
        var imgurl = req.file.location; // router에서 붙인 multer가 반환한 url (aws s3 object url)
    }
    res.json(imgurl);
}

이미지 업로드에 대한 자세한 내용은 이전 포스트 참고.

  1. 적용된 모습

위지윅 에디터가 성공적으로 적용된 모습이다.

위지윅 에디터로 편집한 글이 블로그 글 보기에 그대로 출력되는 모습이다.

좋은 웹페이지 즐겨찾기