[프로젝트] CKEditor 적용해보기
이전 프로젝트에서는 학생들의 피드백을 작성하기 위한 에디터로 Toast UI Editor를 사용하였었다. 그래서 이번 REST API로 리뉴얼 한 프로젝트를 진행할 때에도 Toast UI Editor를 사용하기 위해 적용을 시켜보았는데, 나는 vue3 버전을 사용중이라서 toast ui editor가 vue3 버전에 대해서 지원을 아직 안하는 것 같았다.
그래서 찾아보니 CKEditor라는 vue3 버전도 지원하는 에디터를 알게 되었고 설정이 조금 귀찮기는 하지만 다른 블로그들 예시를 찾아보니 적용할 수 있을 것 같아 한번 시도해보았다! (이러면서 하나씩 알게 되는거지!!)
설정 사이트
CKEditor 사이트에서 바로 원하는 플러그인을 구성해서 적용할 수 있도록 GUI 설정 환경을 제공해주었다. 그래서 천천히 읽어 보고 그래도 좀 기본적으로 피드백들을 작성할 때 필요한 설정들을 추가하며 진행하였다.
https://ckeditor.com/ckeditor-5/builder/
CKEditor 5 Builder
Create and customize your online editor with CKEditor 5 Builder. Choose features, set up your editor, and see changes in real-time.
ckeditor.com
Package 설치하기
npm install ckeditor5
npm install @ckeditor/ckeditor5-vue
styles.css 설정
나는 @/assets/css/styles.css 경로에 넣어주었다.(@는 프로젝트 최상위)
@import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@media print {
body {
margin: 0 !important;
}
}
.main-container {
font-family: 'Lato';
width: fit-content;
margin-left: auto;
margin-right: auto;
}
.ck-content {
font-family: 'Lato';
line-height: 1.6;
word-break: break-word;
}
.editor-container_classic-editor .editor-container__editor {
min-width: 795px;
max-width: 795px;
}
main.js 설정 추가
import {createApp} from 'vue'
import App from './App.vue'
import router from './router/router.js'
import store from './store/index.js'
import '@/assets/css/styles.css'; // 추가한 부분
import CKEditor from '@ckeditor/ckeditor5-vue'; // 추가한 부분
createApp(App)
.use(router)
.use(store)
.use(CKEditor)
.mount('#app')
Vue 컴포넌트 등록
MyEditor라는 컴포넌트 이름으로 등록해주었다.
<template>
<div>
<div class="main-container">
<div class="editor-container editor-container_classic-editor" ref="editorContainerElement">
<div class="editor-container__editor">
<div ref="editorElement">
<ckeditor v-if="isLayoutReady" v-model="config.initialData" :editor="editor" :config="config" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import {
ClassicEditor,
AccessibilityHelp,
Alignment,
AutoImage,
Autosave,
Base64UploadAdapter,
Bold,
Essentials,
Heading,
Highlight,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Italic,
Link,
LinkImage,
List,
ListProperties,
Paragraph,
PasteFromOffice,
SelectAll,
Strikethrough,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TodoList,
Underline,
Undo
} from 'ckeditor5';
import translations from 'ckeditor5/translations/ko.js';
import 'ckeditor5/ckeditor5.css';
export default {
name: 'MyEditor',
data() {
return {
isLayoutReady: false,
config: null, // CKEditor needs the DOM tree before calculating the configuration.
editor: ClassicEditor
};
},
mounted() {
this.config = {
toolbar: {
items: [
'undo',
'redo',
'|',
'selectAll',
'|',
'heading',
'|',
'bold',
'italic',
'underline',
'strikethrough',
'|',
'link',
'insertImage',
'insertImageViaUrl',
'insertTable',
'highlight',
'|',
'alignment',
'|',
'bulletedList',
'numberedList',
'todoList',
'|',
'accessibilityHelp'
],
shouldNotGroupWhenFull: false
},
plugins: [
AccessibilityHelp,
Alignment,
AutoImage,
Autosave,
Base64UploadAdapter,
Bold,
Essentials,
Heading,
Highlight,
ImageBlock,
ImageCaption,
ImageInline,
ImageInsert,
ImageInsertViaUrl,
ImageResize,
ImageStyle,
ImageTextAlternative,
ImageToolbar,
ImageUpload,
Italic,
Link,
LinkImage,
List,
ListProperties,
Paragraph,
PasteFromOffice,
SelectAll,
Strikethrough,
Table,
TableCaption,
TableCellProperties,
TableColumnResize,
TableProperties,
TableToolbar,
TodoList,
Underline,
Undo
],
heading: {
options: [
{
model: 'paragraph',
title: 'Paragraph',
class: 'ck-heading_paragraph'
},
{
model: 'heading1',
view: 'h1',
title: 'Heading 1',
class: 'ck-heading_heading1'
},
{
model: 'heading2',
view: 'h2',
title: 'Heading 2',
class: 'ck-heading_heading2'
},
{
model: 'heading3',
view: 'h3',
title: 'Heading 3',
class: 'ck-heading_heading3'
},
{
model: 'heading4',
view: 'h4',
title: 'Heading 4',
class: 'ck-heading_heading4'
},
{
model: 'heading5',
view: 'h5',
title: 'Heading 5',
class: 'ck-heading_heading5'
},
{
model: 'heading6',
view: 'h6',
title: 'Heading 6',
class: 'ck-heading_heading6'
}
]
},
image: {
toolbar: [
'toggleImageCaption',
'imageTextAlternative',
'|',
'imageStyle:inline',
'imageStyle:wrapText',
'imageStyle:breakText',
'|',
'resizeImage'
]
},
initialData:
'<h2>Congratulations on setting up CKEditor 5! 🎉</h2>\n<p>\n You\'ve successfully created a CKEditor 5 project. This powerful text editor will enhance your application, enabling rich text editing\n capabilities that are customizable and easy to use.\n</p>\n<h3>What\'s next?</h3>\n<ol>\n <li>\n <strong>Integrate into your app</strong>: time to bring the editing into your application. Take the code you created and add to your\n application.\n </li>\n <li>\n <strong>Explore features:</strong> Experiment with different plugins and toolbar options to discover what works best for your needs.\n </li>\n <li>\n <strong>Customize your editor:</strong> Tailor the editor\'s configuration to match your application\'s style and requirements. Or even\n write your plugin!\n </li>\n</ol>\n<p>\n Keep experimenting, and don\'t hesitate to push the boundaries of what you can achieve with CKEditor 5. Your feedback is invaluable to us\n as we strive to improve and evolve. Happy editing!\n</p>\n<h3>Helpful resources</h3>\n<ul>\n <li>📝 Trial sign up,\n <li>📕 Documentation,\n <li>⭐️ GitHub (star us if you can!),\n <li>🏠 CKEditor Homepage,\n <li>🧑💻 CKEditor 5 Demos,\n</ul>\n<h3>Need help?</h3>\n<p>\n See this text, but the editor is not starting up? Check the browser\'s console for clues and guidance. It may be related to an incorrect\n license key if you use premium features or another feature-related requirement. If you cannot make it work, file a GitHub issue, and we\n will help as soon as possible!\n</p>\n',
language: 'ko',
link: {
addTargetToExternalLinks: true,
defaultProtocol: 'https://',
decorators: {
toggleDownloadable: {
mode: 'manual',
label: 'Downloadable',
attributes: {
download: 'file'
}
}
}
},
list: {
properties: {
styles: true,
startIndex: true,
reversed: true
}
},
menuBar: {
isVisible: true
},
placeholder: 'Type or paste your content here!',
table: {
contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableProperties', 'tableCellProperties']
},
translations: [translations]
};
this.isLayoutReady = true;
}
};
</script>
적용 결과
추가해줘야 할 부분들이 많지만 잘 적용된 것을 확인할 수 있었다.
그냥 textarea에 글을 써도되겠지만 그래도 이런 기능들을 적용해보면서 해당 기능을 사용하는 사람의 사용자 경험이 더 올라가는 방향인 것 같아서 이런 결정이 오히려 더 좋은 부분이라고 생각한다!!ㅎㅎ
이제 피드백 기능 구현을 진행해 보아야겠다.