기억의 실마리
2024. 7. 13. 20:17

TinyMCE의 이미지 첨부

기본적으로 이미지 첨부 기능을 제공하지만,

UX를 고려했을 때 사용자에게 익숙하지 않은 방식의

이미지 첨부 기능을 제공하고 있다.

 

  • 기본으로 제공되는 TinyMCE 이미지 첨부 방식

위 이미지 처럼 기본적으로 소스를 붙여넣어서 첨부하는 방식으로

제공되고 있다.

 

이러한 방식은 UX에 좋지 않다는 생각이 들었고

업로드 버튼을 통해 이미지를 업로드하는 방식으로

UX를 향상시키고자 커스텀 방식에 대해 알아보게 되었고

 

실제로 커스텀하여 업로드 버튼을 통해서도 이미지 첨부가

가능하도록 만든 경험과 방법을 공유하고자 포스팅을 하게 됐다.

 

라이브러리는 이전 포스팅 https://zeriong.tistory.com/65

과 동일하게  tinymce/tinymce-react 를 활용하여 구현했다.

 

소스코드

const TinyMceEditor = () => {
  return (
    <Editor
      apiKey={YourApiKey}
      init={{

        // 필요한 툴을 공식 document에서 찾은 후 추가
        plugins: [ ... ],

        // 플러그인에 추가한 것을 툴바에 표시하기 위한 객체(생략)
        toolbar: " ... ",

        // 이미지 툴바 클릭 시 이미지 파일 첨부 설정 추가
        image_title: true,
        automatic_uploads: true,
        file_picker_types: "image",
        
        // 업로드 버튼을 눌렀을 때 실행되는 함수
        file_picker_callback: (callback, value, meta) => {
          const input = document.createElement("input");
          input.setAttribute("type", "file");
          input.setAttribute("accept", "image/*");

          input.addEventListener("change", (e) => {
            const file = e.target.files[0];
            const reader = new FileReader();

            reader.addEventListener("load", () => {
              // 파일 블로핑
              const id = "blobid" + new Date().getTime();
              const blobCache = window.tinymce.activeEditor.editorUpload.blobCache;
              const base64 = reader.result.split(",")[1];
              const blobInfo = blobCache.create(id, file, base64);
              blobCache.add(blobInfo);

              // 콜백을 호출하고 파일 이름으로 파일 데이터(file의 meta) 파일이름 적용
              callback(blobInfo.blobUri(), {title: file.name});
            });
            // 블로핑된 파일 URL을 읽어옴
            reader.readAsDataURL(file);
          });

		  // run function
          input.click();
        },
        
		// ...
        
      }}
    />
  );
};

컴포넌트 형식으로 구현하였고 필요한 코드만을 적어두었다.

나머지 필요 요소는 공식 문서(https://www.tiny.cloud/docs/tinymce/latest/)

를 확인하여 추가해주면 아래 이미지처럼

구현할 수 있게 된다.

 

  • 소스 인풋 옆에 추가된 업로드 버튼

 

마치며...

회사에서 여러 프로젝트를 진행하며 요구사항에 맞춘 라이브러리 커스텀이나 구현해보지 못한기능을 구현하는 일이 점점 잦아지는 것 같다. 새로운 기능을 구현하며 느낀 것 언제나 "정답은 공식문서(Docs)에서 찾을 수 있다." 라는 것이다. 타 블로그나 커뮤니티 글을 찾아보기 이전에 공식문서를 자세히 살펴 본 후 추가적인 아이디어를 얻기 위해 블로그 또는 커뮤니티 글을 참고하여 구현하는 것이 해당 라이브러리에 대한 이해도를 높이면서 활용도를 확장시킬 수 있는 것 같다.

'Frontend > Editor Tool' 카테고리의 다른 글

[ TinyMCE ] 1000회 무료 에디터툴!  (0) 2024.05.04
2024. 5. 4. 13:43

Editor Tool

일반적으로 에디터 툴은 프론트에서 서비스 이용자가

다양한 스타일로 글을 작성할 수록 있도록 돕는 툴이다.

다양한 에디터 툴이 존재하며 필자는 에디터 툴하면

가장 먼저 Toast UI Editor가  떠오른다.

 

필자 역시 개발을 진행하다 보면 에디터 툴이 필요하여

여러 에디터 툴을 알아보았고 Toast UI Editor를

사용하고 싶었으나 리액트 최신 버전을 지원하지 않아

당장은 사용할 수 없는 상황이었다.

 

필자는 리액트를 주력으로 개발하기에

결국 리액트 최신버전을 지원하는 에디터 툴을

찾다가 TinyMCE라는 에디터 툴을 알게되었고

 

해외에서는 꽤 활발한 커뮤니티가 형성되어 있어

접근성이 좋을 것으로 판단했고 리액트 최신버전을

지원하고 있어 선택하게 되었다.

 

TinyMCE

이번에 소개할 에디터 툴은 TinyMCE이다.

회원가입 시 계정 API key를 제공하고

월 1,000회 로드를 무료로 제공하고 있다.

 

Microsoft, NASA, DRIFT, ATLASSIAN 등 해외 유명 기업에서

많이 활용되고 있고 확장성이 뛰어나 다양하게

활용할 수 있는 장점이 있고

 

React 주력 개발자로서 React 최신버전을 지원한다는

면이 필자는 가장 마음에 들었다.

또한 React, Vue, Angular, JAVA 등 다양한 언어를

지원하고 있어 주력 에디터로서도

좋은 선택지라는 생각이 들었다.

 

Install

npm install --save @tinymce/tinymce-react

 

 

예시코드

import React from 'react';
import { Editor } from '@tinymce/tinymce-react';

export default function App() {
  return (
    <Editor
      apiKey='your api key'
      init={{
        plugins: 'anchor autolink charmap codesample emoticons image link lists media searchreplace table visualblocks wordcount checklist mediaembed casechange export formatpainter pageembed linkchecker a11ychecker tinymcespellchecker permanentpen powerpaste advtable advcode editimage advtemplate ai mentions tinycomments tableofcontents footnotes mergetags autocorrect typography inlinecss markdown',
        toolbar: 'undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image media table mergetags | addcomment showcomments | spellcheckdialog a11ycheck typography | align lineheight | checklist numlist bullist indent outdent | emoticons charmap | removeformat',
        tinycomments_mode: 'embedded',
        tinycomments_author: 'Author name',
        mergetags_list: [
          { value: 'First.Name', title: 'First Name' },
          { value: 'Email', title: 'Email' },
        ],
        ai_request: (request, respondWith) => respondWith.string(() => Promise.reject("See docs to implement AI Assistant")),
      }}
      initialValue="Welcome to TinyMCE!"
    />
  );
}

Tiny MCE에서 제공하고 있는 아주 간단 소개정도의 구현코드이다.

ai_request 기능을 제공하고 있어 ai를 활용할 수 있는

몇가지 기능도 제공하는 것으로 보인다.

 

다음에는 현재 필자가 직접 커스텀한 방식이나 방법에 대해서

Tiny MCE 게시글을 추가적으로 포스팅할 예정이다.

 

마치며...

서비스 이용자로서 에디터 툴은 많이 사용해봤지만 막상 서비스를 만드는 개발자 입장에서 에디터 툴을 직접 구현하기 위해서는 복잡하고 많은 프로세스를 요구한다는 것을 깨닫고 직접적으로 구현한다는 것은 매우 어렵다는 것을 깨달았다. 좋은 에디터 툴을 라이브러리로 제공하는 선두 개발자들에게 깊은 감사를 느꼈다... 그리고 이번 경험으로 또 하나의 목표가 생겼다. 바로 에디터 툴을 직접 구현해보는 것이다. 혼자의 힘으론 어려울 수 있겠지만 분명 좋은 경험이 될 것 같다.