Summernote

섬머노트는 "이지윅 에디터"로 우리들이 사용하는 게시판등에서 글꼴, bold 혹은 이미지 삽입 등을 사용할 때 사용하는 기능들을 추가해주는 라이브러리이다.

https://summernote.org/

 

티스토리의 이지윅

이와같은 기능을 간편하게 사용할 수 있는 라이브러리 중 하나로 Summernote이다.

 

오늘은 섬머노트를 사용하여 이미지 삽입, 및 css 적용을 진행한다.


writer.php(게시물 등록)

필요한 라이브러리를 import 받는다 이는 css, jquery 등이 포함된다.

....
// 관련 라이브러리를 cdn으로 import
<!-- include libraries(jQuery, bootstrap) -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

<!-- include summernote css/js -->
<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.js"></script>
<div style="width: 100%; height:100%">
....

 

섬머노트가 적용될 태그 하위에 섬머노트 태그를 작성

<div style="width: 80%; height:80%; margin: 50px"> 
    <form method="POST" id="write_form">
      <div style="height: 20%;"> 
        <div class="form-floating mb-3">
          <input type="text" name="title" class="form-control" id="floatingInput" placeholder="name@example.com"
          value="<?php
              if ($isSubmit) {
                echo $_POST['title'];
              }
            ?>"/>
          <label for="floatingInput">제목</label>
        </div>
      </div>
  
  
        <div >
          <div class="form-floating">
          // 섬머노트를 textarea 태그로 생성하였으며 이는 데이터를 전송할 form을 사용하기 위함
          // div도 가능하며 id를 "summernote"로 주면 된다.
          <textarea id="summernote" name='content'></textarea >
        </div>
        
          <input hidden/ value="submit" name="is_submit">
        

        <div style="margin-top: 20px;">

          <button onclick="formSubmit()" style="margin-left: 20px" type="button" class="btn btn-primary" >작성</button>
          <span>
            <?php
              if($isSubmit)
              echo "제목, 내용을 확인해주세요";
            ?>
          </span>
        </div>

    </form>

  </div>

 

 

섬머노트의 틀은 적용이 된 모습을 확인 할 수 있다.

그러나 이미지 삽입의 경우 동작하지만 저장되지는 않을 것 이다. 이는 이미지 삽입의 동작 원리를 알아야한다.

 

1. 이미지 삽입

2. 이미지가 서버에 올라가 특정 경로에 저장된다.

3. 이미지가 저장된 경로와 저장된 파일명을 화면으로 반환한다.

4. 경로와 파일명으로 하면에 img태그를 상성한다.

5. 저장버튼을 눌러 저장한다.

6. 저장 내용은 이미지 태그를 포함한 내용이 저장된다.

위 과정을 위해 이미지 업로드 기능을 만들어야한다.

 

writer.php (섬머노트의 업로드 동작을 위한 스크립트)

<script>
    $(document).ready(function() {
    // 높이, 언어, 폰트 등 다양한 설정을 할 수 있는 섬머노트의 옵션설정
        var $summernote = $('#summernote').summernote({
          lang: 'ko-KR',
          height: 400,
          // 콜백 함수 특정 기능들을 할 때 수행할 함수를 지정한다.
          callbacks: {
          // 이미지 업로드를 하면 아래의 함수가 동작한다.
            onImageUpload: function(files) {
              if(files.length > 4) {
                alert('파일은 3개 까지만 등록 할 수 있습니다.')
                return
              }
              for(var i = 0; i < files.length; i++){
              // 각각의 파일들을 sendFile이라는 함수의 인자로 전달한다.
                sendFile($summernote, files[i])
              }
            }
          }
        });
    });

    function sendFile(el, file) {
      console.log('111')
      console.log(el)
    var formData = new FormData();
    formData.append("file", file);
    // file 데이터를 ajax를 통해 uplload_file.php로 Post방식으로 전달한다.
    $.ajax({
        url: '/board/upload_file.php',
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST',
        success: function (data) {
            if(data==-1){
                alert('용량이 너무크거나 이미지 파일이 아닙니다.');
                return;
            }else{
                console.log(window.location.href+data)
                // 반환 받은 이미지 경로를 통해 summernote의 내부에 img 태그를 생성한다.
                el.summernote('insertImage', data, function ($image) {
                    $image.attr('src', data);
                    $image.attr('class', 'childImg');
                });
                var imgUrl=$("#imgUrl").val();
                if(imgUrl){
                    imgUrl=imgUrl+",";
                }
                $("#imgUrl").val(imgUrl+data);
            }
        }
    });
  }

  function formSubmit() {
    var form = document.getElementById('write_form')
    form.submit()
  }
  </script>

 

upload_file.php (파일 업로드 작업을하는 서버코드)

<?php
// ini_set('display_errors', 1);
// POST 방식일 때만 동작
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    if($_FILES['file']['size']>10240000){//10메가
      echo "-1";
      exit;
    }

    $ext = substr(strrchr($_FILES['file']['name'],"."),1);
    $ext = strtolower($ext);

    if ($ext != "jpg" and $ext != "png" and $ext != "jpeg" and $ext != "gif")
    {
      echo "-1";
      exit;
    }

	// 이름의 중복이 있을 수 있기때문에 rand함수를 사용하여 임의의 문자열로 만든다.
    $name = "mp_".$now3.substr(rand(),0,4);
    $filename = $name.'.'.$ext;
    $date = date("Y-m-d",time());
    $dir ='../files/'.$date;
    
    //files의 경로에 오늘 날짜로 된 디렉토리가 없다면 디렉토리를 생성한다.
    // 이는 관리를 수월하게 하기위함일 뿐 없어도 문제는 없다.
    if (!file_exists($dir)) {
      mkdir($dir, 0777, true);
    }
    
    $destination = $dir.'/'.$filename;
    $location =  $_FILES["file"]["tmp_name"];
    // 전달받은 file을 files/오늘날짜/파일명. 확장자 형식으로 저장한다.
    move_uploaded_file($location,$destination);
    
    //이미지 파일의 경로를 반환한다.
    echo '/files/'.$date.'/'.$filename;
  }
?>

 

이미지를 업로드하면 "/files/오늘날짜/파일명.확장자" 형식으로 파일이 저장 되는 것을 확인한다.

 

png 파일 생성 확인

 

summernote 태그 내부에도 이미지가 삽입된 것을 확인

summernote에서 html 태그를 확인 할 수도 있다 "</>" 버튼을 눌러보자

이미지 삽입이 된 것을 확인
이미지 태그에 반환 받은 경로가 들어있는 것을 확인

 

다음에는 XSS방지를위한 html_entites를 적용하여 해당 내용을 저장하는 기능을 추가해보자.

 

+ Recent posts