이번 프로젝트에 포함된 html에디터중 썸머노트는 부트스트랩과 충돌이 많아서 적용하다가 빠른 포기를 하고 ckeditor를 선택했다. 그런데 이것도 부트스트랩 모달쪽하고 충돌이 있었는데(이미지 위젯이 표시가 안되는 문제)그래서 입력은 페이지에서 하도록 변경해서 진행했다.
우선 설치
설치는 ckeditor에 가셔서 qickstart를 보면 친절히 안내되어있다.
ckeditor5를 사용했다. 여러 방식이 있으니 아래 가셔서 원하는 방법을 선택하시면 된다.
https://ckeditor.com/docs/ckeditor5/latest/builds/guides/integration/installation.html
그중 onlin builder를 사용했는데 원하는 플러그인을 추가할 수 있고 언어도 선택할 수 있어서 여러모로 편리했다.
다운받은 압축파일을 풀어서 프로젝트 소스에 넣어주고 해당 경로를 지정해 jsp에 추가해주었다.
ckeditor는 div나 textarea에 id 혹은 class로 지정해주고 자바스크립트를 통해 editor를 생성해준다.
▼ body html
<div id="writeEditor" style="display: none;"></div>
display:none;으로 둔 이유는 안쪽에 생성이 아닌 형제노드로 editor가 생긴다.
▼ js는 하단에 넣어주었다.
<script>
let editor;
ClassicEditor
.create( document.querySelector( '#writeEditor' ) , {
ckfinder: {
uploadUrl: 'http://localhost:8123/admin/test/imageUpload'
}
} )
.then( newEditor => {
editor = newEditor;
} )
.then( editor => {
window.editor = editor;
} )
.catch( error => {
console.error( 'Oops, something went wrong!' );
console.error( 'Please, report the following error on https://github.com/ckeditor/ckeditor5/issues with the build id and the error stack trace:' );
console.warn( 'Build id: g64ljk55ssvc-goqlohse75uw' );
console.error( error );
} );
</script>
let edior는 에디터 노드의 정보를 가져오기 위해 있고, 공식 문서에 나와있는 생성법을 넣었다.
플러그인으로 ckfinder upload image인가 그걸 가져와서 업로드 요청을 하고 결과 url를 리턴해주면 에디터 안에 이미지를 생성해준다.
우선 이미지 업로드
이미지 업로드는 ckfinder를 사용 uploadUrl에 요청 주소를 적어둔다. 그러면 parmeter로 multipartFile을 보내게 되니 컨트롤러에서 받아주었다.
페이지 이동이 없고 이미지 url를 줘야되니 ajax통신을 하는 것 같아서 @responseBody를 추가해주었다.
@ResponseBody
@RequestMapping("imageUpload")
public Map<String, Object> imageUpload(@RequestParam("upload") MultipartFile image) {
Map<String, Object> data = new HashMap<String, Object>();
if(image != null) {
String originalName = image.getOriginalFilename();
CreateUploadFolderUtil imgSaveFolder = new CreateUploadFolderUtil(image);
String imgPath = imgSaveFolder.imgSave();
data.put("uploaded", 1);
data.put("fileName", originalName);
data.put("url", "http://localhost:8123" + imgPath);
}
return data;
}
이미지를 업로드하면 FormData에 upload로 되어있어 requestParam에 위 값을 주었다.
CreateUploadFolderUtil은 날짜별로 폴더생성하고 UUID로 이름등을 생성해서 가져오도록 만든 클래스이다.
나머지는 이미지 정보를 서버에 저장하기 위한 이름 추출과 새로운 이름주고 완성된 것을 리턴해주었다.
여기서 오랜만에 이미지업로드를 해서 해매다가 아침에 일어나보니 서버에 폴더를 따로 설정안해줬던게 있어서 해결했다.
톰캣 더블클릭 후 해당 페이지 하단에 모듈을 누르고 external 모듈 추가해서 지정하면댄다.
그리고 이미지 업로드를 하기 전에 maven과 servlet 설정을 해줘야한다.
pom.xml에 디펜던시 추가해주고
<!-- 업로드용 파일 파서... -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!-- json 변환기 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
servlet-context에서 bean을 등록해서 생성해야한다.
<!-- 파일 업로드 -->
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="-1"></beans:property>
</beans:bean>
여기서 value -1은 제한이 없다는 건데 나중에 지정하고 예외처리등을 해야한다.
이제 이미지를 등록하면 뿅하고 등장한다.
이제는 이미지와 등록된 글을 db에 저장을 해야될 시간이다.
<script>
function uploadData() {
const editorData = editor.getData();
console.log(typeof(editorData));
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState==4&&xhr.status==200) {
}
}
xhr.open("post", "../test/uploadTest", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
xhr.send("editorData="+editorData);
}
</script>
일전에 에디터를 담아둔 editor변수에 getData()를 하면 안에 내용을 String으로 리턴해준다. (잘 안되길래 typeof()를 하니 문자열이였다)
이값을 문자 넘기듯이 스프링에 넘겨주면된다. 값은 태그와 문자로 이루어진 html코드와 같이 넘어간다.
이부분 컨트롤러는 다른 곳에서도 많으니 생략
db에 등록된 html코드를 불러와야한다. 스프링구간은 다른 곳에서 많으니 생략하겠다. (참고로 Model에 담아서 가져왔다.)
불러올때 아쉽게도 js를 작성해야했다....
왜냐하면 태그의 class로 값을 보내버려서 이를 알아채줄 css가 필요한데 이 css는 ckeditor의 js가 에디터를 만들면 불러오는 것같다.
그래서 에디터가 생성되면 읽을 수만 있고, 상단 툴바를 지워주어야한다.
이부분은 문서에 readonly를 검색하니 찾을 수 있었다.
<div id="readEditor">
${uploadFile.test_content }
</div>
<script>
ClassicEditor
.create( document.querySelector( '#readEditor' ))
.then( editor => {
window.editor = editor;
editor.isReadOnly = true;
const toolbarElement = editor.ui.view.toolbar.element;
toolbarElement.style.display = 'none';
} )
.catch( error => {
console.error( 'Oops, something went wrong!' );
console.error( 'Please, report the following error on https://github.com/ckeditor/ckeditor5/issues with the build id and the error stack trace:' );
console.warn( 'Build id: g64ljk55ssvc-goqlohse75uw' );
console.error( error );
} );
</script>
다음과 같이 설정하면 readEditor id를 가진곳 밑에 에디터를 만들고 안쪽에 가져온 값을 입력하도록 되어 있다.
이로써 이미지업로드 부터 저장, 생성까지 해보았다.
그리고 불편한게 이미지를 문단에 넣을려면 드래그해서 하면된다.