커스텀하기 편한 위지윅 에디터 (TinyMCE)

JeongHoon Park·2022년 4월 6일
4
post-thumbnail

WYSIWYG 에디터란

WYSIWYG는 What You See Is What You Get, "보는 대로 얻는다"라는 문장의 줄임말이다. 문서를 편집하는 과정에서 화면에 보이는 문장이나 글 맵시 등을 동일하게 화면에 출력해주는 방식이다. 위지위그 에디터는 이러한 기능을 위해서 사용자는 모르게 <p>, <span>, <em style=> 등 다양한 HTML 소스를 입력해주고 있다.

프로젝트를 하다보면 단순 input이나 textarea로는 부족한 경우가 많다. 예를 들면 블로그 글을 작성할 때나 쇼핑몰에 제품 설명을 적어야 하는 경우를 떠올리면 이해가 빠를 것이다. 잘 구현을 한다면 충분할 수도 있지만 위지위그 방식이 아니라면 사용자 입장에서 내가 쓴 글이 어떻게 출력이 되는지 확인 후에 다시 수정을 하는 번거로운 과정이 추가된다. 그래서 이번 프로젝트에서 위지위그 에디터를 활용하게 되었다.


TinyMCE 선택한 이유

시중에는 정말로 많은 WYSIWYG 에디터가 존재하기 때문에 우리는 TinyMCE를 선택하기 위한 몇가지 조건을 만들었다. 우선 UI 커스터마이징에서 자유로워야할 것. 아무리 이쁜 디자인, 좋은 기능의 에디터여도 우리가 만들 사이트에 녹아들지 않는다면 사용할 수 없었다.

두번째, 무료 버전으로도 충분히 기능 구현이 가능할 것. 개발을 하다보면 기능이 추가되거나 줄어들거나한다. 그렇기 때문에 무료 버전이 지원하는 기능이 너무 타이트하다면 원치 않는 지출이 늘어나거나 최악의 경우 다른 에디터로 변경해야하는 일이 생길 수 있었다. 그렇기 때문에 무료 버전으로도 충분한 기능 구현이 되는지가 중요했다.

마지막으로는 지속적인 인지도였다. 인지도가 있다는 것에는 많은 의미가 포함되어 있었다. 사람들이 많이 사용을 했고 그에 대한 참조 문서가 많았으면 했다. Docs에도 충분한 설명이 있지만 가끔은 필요한 기능을 구현하기 위해서 Docs에 없는 방식으로 구현을 해야할 때도 있었다. 그리고 지속적으로 많은 사람들이 사용하고 있다는 것은 많은 사람들이 많은 실험 혹은 개발 경험을 거쳤을 것이라는 의미라고 생각되었다.

TinyMCE 이외에도 CKeditor, Trix, Summernote, Draft.js 등 많은 에디터들이 후보에 올랐었다. 하지만 결국 위 모든 조건을 가장 넉넉하게 통과한 에디터는 TinyMCE였다.


TinyMCE 커스텀하기

기본 스타일 커스텀

TinyMCE는 기본적인 UI 옵션을 제공한다. 해당 옵션들은 TinyMCE docs에서도 설명이 잘 되어있느니 내가 사용했던 것들만 간단히 집고 넘어 가겠다.

우선 TinyMCE는 메뉴바와 툴바 모두 제공한다. 하지만 우리의 경우 툴바만 필요했기에 menubar: false,를 추가하여 메뉴바는 보이지 않게하였다.

그리고 툴바를 제공하는 것뿐만 아니라 내부 요소들을 원하는 것들로만 원하는 위치에 원하는 것들끼리 묶을 수 있게 커스터마이징이 가능하다. toolbar: 'undo redo | bold italic underline', 이와 같이 원하는 버튼의 키워드를 string 형식으로 적어주고 |기호를 사용하여 나눠주면 툴바 버튼들 사이에 보더가 생긴다.

그리고 좀더 깔끔한 UI를 위해서 상태바를 삭제하였다. 현재 상태를 알 수 있지만 디자인적으로 지저분해보였다. statusbar: false, 이 옵션을 false로 두면 상태바를 없앨 수 있다.


TinyMCE에서 제공하지 않는 스타일 커스텀

우리는 TinyMCE의 디자인을 좀더 세세하게 커스텀하기를 원했다. 툴바 버튼 사이의 보더의 굵기나 색을 변경한다거나 툴바 버튼의 크기를 바꾸거나 TinyMCE 전체 보더를 안보이게 하거나 등등.

우리 팀은 TinyMCE를 처음 써봤기 때문에 이 문제를 어떻게 해결할 수 있는지 몰랐기에 Docs를 탈탈 털었지만 결국 Docs에서는 해당 기능을 찾지 못하였다. 위처럼 TinyMCE가 제공하는 옵션으로 커스터마이징이 되었다면 좋았겠지만 그렇지 않았던 것이다. 결국 TinyMCE에 스타일을 !important로 주는 것으로 해결했다.

TinyMCE의 소스 코드를 보면 자체적으로 class명이 설정되어있다. 우리가 원하는 요소의 class명을 찾아 직접적으로 스타일링을 해주었다.

// Emotion 코드입니다.
& .tox-toolbar__group {
    border-color: #F9F5F3 !important;
  }

이미지 모달 버튼 + 이미지 삽입

게시물에는 글뿐만 아니라 이미지도 넣어야 때가 많다. 우리 프로젝트에서도 이미지를 넣어야했었고 TinyMCE에서 이미지 플러그인과 UI를 제공해준다. 하지만 문제는 제공해주는 이미지 선택 UI가 이쁘지 않았다.

그래서 직접 디자인한 모달을 사용하여 이미지를 삽입하기로 결정했다. 여기서 두가지 기능이 필요하다. 우선 TinyMCE의 버튼을 활용하여 모달을 켜고 끄는 것과 외부 모달을 이용하여 이미지를 TinyMCE 에디터 안에 삽입하는 기능이다.

툴바 버튼 만들기

TinyMCE는 툴바 또는 메뉴바 버튼을 새롭게 만들 수 있다. 우리는 툴바 버튼을 생성하여 해당 버튼을 모달에 연결해주었다.

<Editor
  init={{
    toolbar: 'custom_button',
    setup: (editor) => {
      editor.ui.registry.addButton('custom_button', {
      icon: 'image',
      onAction: () => setIsShowModal(true),
      });
    },
  }}
/>

위의 toolbar의 custom_button은 TinyMCE에서 제공해주는 옵션이 아니다. 우리가 새롭게 생성할 버튼이다. toolbar에서 설정 후 setup에서 위와 같이 버튼을 만들어주면 된다.

editor.ui.registry.addButton()의 경우 두가지 인자를 받는다. 첫번째는 버튼 이름이다. toolbar에서 미리 설정해놓은 이름을 적어주면 된다. 두번째는 객체로 되어있고 객체에는 버튼에 필요한 요소들을 설정할 수 있다. 위처럼 해당 객체에 icon에 기존에 TinyMCE에서 제공해주는 아이콘명을 적어줘도 되고 이미지를 따로 임포트해줘도 괜찮다. 그리고 onAction 안에 해당 버튼이 어떤 동작을 할지 설정하면 툴바 버튼 만들기는 마무리된다.

이미지 삽입하기

이미지 삽입하기는 간단하다. 하지만 예제가 모두 바닐라 JS용 예제만 존재해서 방법을 찾는데 오래걸렸다. TinyMCE 자체도 하나의 textarea이기 때문에 내용을 useState로 관리를 한다.

setState((state) => state+<img src="이미지 경로" />);

위 코드로 간단하게 이미지를 삽입 가능하다.


TinyMCE 설정 추상화

TinyMCE 에디터를 처음 글을 등록할 때도 사용하지만 이미 쓴 글을 수정할 때도 에디터가 필요했다. 수정페이지에서 사용해야하는 재사용성의 문제도 있지만 커스텀을 많이 하다보니 설정을 위한 코드가 점점 길어졌고 해당 코드를 JSX의 HTML부분에 넣었을 때 파일 구조를 보기 힘들어져서 설정 코드를 따로 추상화하기로 결정했다.

// config.ts
export const EDITOR_CONFIG = {
  id: 'tinyEditor',
  init: {
    menubar: false,
    statusbar: false,
    ...설정
  },
};

// EditorContainer.tsx
...
<Editor
  {...EDITOR_CONFIG}
/>;
...

위의 코드처럼 EDITOR_CONFIG 코드를 따로 추상화하여 불러와서 사용하였다.


마무리

이 글에서는 TinyMCE 위지위그 에디터를 사용해보며 커스터마이징한 경험에 대해 작성했다. 기본 설정이나 TinyMCE에서 제공하는 커스터마이징은 Docs에도 잘 나와있지만 Docs에 나와있지 않은 것들도 충분히 자유롭게 커스터마이징이 가능했기 때문에 만족감이 매우 높았다.

많은 분들이 프로젝트에 위지위그 에디터를 사용할텐데 안정적이고 무료 버전으로도 충분한 기능 구현이 가능하며 커스터마이징이 자유로운 에디터를 찾는다면 TinyMCE를 추천한다.

profile
Develop myself, FE developer!

0개의 댓글