라라벨에서 TOAST UI 에디터 사용하기 free

2019-09-17

어제 xly.kr에 44개의 컨텐트를 업로드하고 조급한 마음에 검수를 철저히 안하고 공유했더니 부 글이 제대로 표현되지 않는 문제가 있었습니다.


문제의 원인은 컨텐트 본문에 포함된 예제 코드들이 문제를 으킨 것이었습니다. 이메로 발송했던 걸 HTML로 변환해서 넣고 이를 다시 뷰에 표현하는 과정에서 문제가 발생한 것인데요. 이래저래 다양한 방법을 시도해보다가 어차피 나중에 추가해야하는 기능이 이번 참에 WYSIWYG 에디터를 도입해결하기로 결심했어요. 아무래도 개발 컨텐트다 보니 코드도 쉽게 작성할 수 있어야하고 해서 마크다운으로 작성이 가능한 에디터를 찾아보니 NHN에서 공개한 TOAST UI 에디터가 눈에 띄었습니다.


TOAST UI 에디터는 해외에서도 굉장히 평을 받고 있는 것 같습니다. 그런데 벨에서 TOAST UI 에디터를 사용하는 방법을 정리한 글을 찾기가 힘들더군요. 그래서 벨에서 TOAST UI 에디터를 사용하는 방법을 정리해봤습니다.


에디터를 화면에 띄워보자


벨 설치


`<span class="il">laravel</span>  new tui
`

뷰 준비


resources/views/tui.blade.php를 만들고 아래와 같이 작성합니다.


`<!DOCTYPE html>
<html>
<head>
<script src="{{ mix('/css/app.css') }}"></script>
</head>
<body>
<h1>TOAST UI 에디터 예제</h1>
<div id="editSection"></div>
</body>
<script src="{{ mix('/js/app.js') }}"></script>
</html>
`

우트 변경


/에 접근시 준비한 뷰를 보여줄 수 있도록 우트를 아래와 같이 변경합니다.


`<?php

Route::get('/', function () {
return view('tui');
});
`

에셋 컴파


에셋이 컴파되지 않아서 뷰의 mix('/js/app.js') 구문에서 에러가 납니다. 에셋을 컴파합니다.


`npm install
npm run dev
`

웹 브우저로 /를 방문해봅니다.


내용만 나오고 에디터는 나오지 않고 있는걸 확인합니다.


TOAST UI 에디터 설치


`npm install --save tui-editor
`

app.js에 의존성 추가 및 Editor 클래스 초기화


app.js 에 다음의 내용을 추가합니다.


`// 에디터에 필요한 의존성 추가
require('codemirror/lib/codemirror.css'); // codemirror
require('tui-editor/dist/tui-editor.css'); // editor ui
require('tui-editor/dist/tui-editor-contents.css'); // editor content
require('[highlight.js/styles/](http://highlight.js/styles/)github.css'); // code block highlight

var Editor = require('tui-editor');

var editor = new Editor({
el: document.querySelector('#editSection'),
initialEditType: 'markdown',
previewStyle: 'vertical',
height: '300px'
});
`

변경된 내용이 있으니 에셋을 다시 컴파합니다.


`npm run dev
`

이제 ‘/‘에 접근하면 다음과 같이 에디터가 나타날 것입니다.


폼 전송 예제


에디터에 작성하기만 해서는 아무짝에도 쓸모가 없습니다. 에디터로 작성한 내용을 서버로 전송해서 저장을 하고 이를 불러와서 화면에 표현할 수 있어야 의미가 있겠죠. 간단한 CRUD 예제를 만들어봅시다.


POST 모델 추가


`php artisan make:model Post -a
`

-a는 마이그레이션, 팩토리, 리소스 컨트롤러도 함께 만드는 옵션입니다.


마이그레이션


새로 추가된 마이그레이션 파(XXX_create_posts_table.php는 이름으로 생성되어있을 겁니다.)을 열어 content 컬럼을 추가해줍니다.


`public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->text('content');
$table->timestamps();
});
}
`

마이그레이션을 실행합니다.


`php artisan migrate
`

DB 설정이 잘못되어 있으면 에러가 날텐데, 잘 해결하시리 믿습니다. ^^


폼 작성


에디터를 띄운 /에 폼을 추가해보도록 하겠습니다.


resources/views/tui.blade.php를 다음과 같이 수정합니다.


`<!DOCTYPE html>
<html>
<head>
<script src="{{ mix('/css/app.css') }}"></script>
</head>
<body>
<h1>TOAST UI 에디터 예제</h1>
<div id="editSection"></div>
<form action="/posts" method="POST">
@csrf
<textarea name="content" style="display:none"></textarea>
<input type="submit">
</form>
</body>
<script src="{{ mix('/js/app.js') }}"></script>
</html>
`

textarea가 보이지 않도록 display:none 으로 설정했습니다. 제출 버튼을 누르면 TOAST UI 에디터에 작성한 내용을 textarea에 채워서 전송할 겁니다. 이 작업을 편히 하기 위해 jquery를 추가합니다.


`npm install jquery
`

resources/js/app.js 파에 아래 구문을 추가합니다.


`window.$ = require("jquery");
`

다시 에셋을 컴파하면 어디서든 $로 jquery를 사용할 수 있습니다.


에디터 객체도 페이지에서 사용할 수 있도록 Editor도 window에 할당합니다. Editor 객체 초기화하는 코드는 뷰로 옮깁니다. 이 단계에서 app.js는 다음과 같습니다.


`require('./bootstrap');

// deps for editor

require('codemirror/lib/codemirror.css'); // codemirror
require('tui-editor/dist/tui-editor.css'); // editor ui
require('tui-editor/dist/tui-editor-contents.css'); // editor content
require('[highlight.js/styles/](http://highlight.js/styles/)github.css'); // code block highlight

window.Editor = require('tui-editor');

window.$ = require("jquery");
`

뷰는 다음과 같이 바꿉니다.


`<!DOCTYPE html>
<html>
<head>
<script src="{{ mix('/css/app.css') }}"></script>
</head>
<body>
<h1>TOAST UI 에디터 예제</h1>
<div id="editSection"></div>
<form action="/posts" method="POST">
@csrf
<textarea name="content" style="display:none"></textarea>
<input type="submit">
</form>
</body>
<script src="{{ mix('/js/app.js') }}"></script>
<script>
var editor = new Editor({
el: document.querySelector('#editSection'),
initialEditType: 'markdown',
previewStyle: 'vertical',
height: '300px'
});

$('form').submit(function(e){
e.preventDefault();

$('textarea').val(editor.getHtml());

this.submit();
});
</script>
</html>
`

app.js에 있던 Editor 초기화 코드를 옮겨왔습니다.


폼을 전송하면 이를 가로채서 에디터의 내용을 textarea에 넣어 보냅니다. 에디터의 내용을 가져올 때 editor.getHtml()을 사용했습니다. HTML로 변환되기 전의 컨텐트를 가져오려면 editor.value()를 쓰면 됩니다.


저장


우트에 Post 리소스 우트를 추가합니다.


`// routes/web.php

Route::resource('posts', 'PostController');
`

PostController store 메소드를 작성합니다.


`public function store(Request $request)
{
$post = Post::create($request->all());

return redirect(route('posts.show', $post->id));
}
`

content값을 저장할 수 있도록 Post $fillable을 설정해줍니다.


`class Post extends Model
{
protected $fillable = ['content'];
}
`

확인


resources/views/posts/show.blade.php 을 만들고 아래 내용을 입력합니다.


`<!DOCTYPE html>
<html>
<head>
<script src="{{ mix('/css/app.css') }}"></script>
</head>
<body>
<h1>TOAST UI 에디터 예제</h1>
<div>{{ $post->content }}</div>
</body>
<script src="{{ mix('/js/app.js') }}"></script>
</html>
`

에디터로 입력했던 값이 HTML 태그와 함께 보여질 것입니다. {{ }}는 기본적으로 이스케이핑을 하기 때문입니다. HTML 태그가 실제로 동작하게 하려면 {{ }}  {!! !!}로 바꿔줍니다.


`<!DOCTYPE html>
<html>
<head>
<script src="{{ mix('/css/app.css') }}"></script>
</head>
<body>
<h1>TOAST UI 에디터 예제</h1>
<div>{!! $post->content !!}</div>
</body>
<script src="{{ mix('/js/app.js') }}"></script>
</html>
`

마치며


이상으로 벨에서 TOAST UI 에디터를 이용해서 글을 작성, 저장, 조회 해봤습니다. 허접한 코드지만 동작은 하니 아예 감을 못잡으시는 분들께는 도움이 될거 생각합니다. 이제 도구는 마련해두었으니 내은 제대로 글을 읽으실 수 있게 싹 손 봐두겠습니다. (내까진 안보이는 글이 꽤 있을거에요 ㅠ)  xly.kr에 버그가 있으면 언제든 연락주세요~!


1 1  54

2019년 9월 17


이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.