장고:썸머노트 설치: 두 판 사이의 차이

학교의 모든 지식. SMwiki
둘러보기로 이동 검색으로 이동
(새 문서: {{장고}} == 개요 == 일반적인 textarea에서 표현할 수 있는 방식은 굉장히 적다. 적어도 위키처럼 목차관리를 해준다든가, 링크를 만든다든가...)
 
편집 요약 없음
 
(사용자 2명의 중간 판 9개는 보이지 않습니다)
1번째 줄: 1번째 줄:
{{장고}}
{{장고}}


== 개요 ==
==개요==
 
===WYSIWYG===
위징위그. What You See Is What You Get 의 약자이다. 일반적으로 입력을 하면 코드를 사용하여 입력을 해야 사용자가 원하는 크기, 색의 글을 쓸 수 있다. 제대로 된 게시판, 사용자 친화적인 게시판이 되기 위해선 필수적인 기능이다.
 
네이버 스마트에디터, MediumEditor, 섬머노트 등이 오픈되어있다.
 
 
일반적인 textarea에서 표현할 수 있는 방식은 굉장히 적다. 적어도 위키처럼 목차관리를 해준다든가, 링크를 만든다든가 정도는 되야 하지 않을까. 많이 사용되는 에디터인 섬머노트를 장고에 설치해본다.
일반적인 textarea에서 표현할 수 있는 방식은 굉장히 적다. 적어도 위키처럼 목차관리를 해준다든가, 링크를 만든다든가 정도는 되야 하지 않을까. 많이 사용되는 에디터인 섬머노트를 장고에 설치해본다.


이미 장고앱으로 개발되어 있어 쉽게 설치가 가능하다.
이미 장고앱으로 개발되어 있어 쉽게 설치가 가능하다.


== 과정 ==
=django-summernote 모듈로 설치하는 방법=
이 방법보다 부트스트랩 위에 올리는 방법이 더 괜찮다;;(2022.05기준 반응형으로 넣기 어렵다.) 이 방법은 쓰지 말자.
{| class="wikitable"
{| class="wikitable"
|+
|+
25번째 줄: 33번째 줄:


추가
추가
|-
|settings.py 설정
|클릭재킹 방지설정 변경.
'django.middleware.clickjacking.XFrameOptionsMiddleware'라는 미들웨어가 클릭재킹을 방지해주는데, 기본설정이 DENY다.
때문에 아래 옵션을 주어 설정을 변경해준다.<syntaxhighlight lang="python">
#클릭재킹 방지설정 변경
X_FRAME_OPTIONS = 'SAMEORIGIN'
</syntaxhighlight><br />
|-
|-
|urls.py 변경
|urls.py 변경
53번째 줄: 70번째 줄:
         model = Post
         model = Post
         fields = ['title', 'content']
         fields = ['title', 'content']
         widgets = {
         widgets = {'content': SummernoteWidget(),}
            'content': SummernoteWidget(),
</syntaxhighlight>폼까지 완성했으면 기존의 탬플릿이 잘 작동하나 확인해본다.
        }
 
<nowiki>혹시나 {{</nowiki>
|-
|탬플릿 변경
|<nowiki>썸머노트로 입력한 내용은 html코드로 나온다. 탬플릿 필터 |safe 를 사용하여 detail.html의 콘텐츠 부분을 다음과 같이 수정한다.</nowiki><syntaxhighlight lang="html+django">
<div class="card-text" style="white-space: pre-line;">{{ question.content| safe  }}</div>
</syntaxhighlight>
</syntaxhighlight>
|}
|}
근데, 이 섬머노트는 반응형이 아니다; 반영할 수 있는 방법이 있을까?
<br />
=부트스트랩 위에 올리기=
===시작 전에===
미디어 설정을 해주는데... 확인이 필요하다. summernote에선 DB에 바로 저장해버리는듯.
{| class="wikitable"
|-
|settings.py 설정
|이미지 업로드를 위해
<code>MEDIA_URL = '/media/'</code>
<code>MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')</code>
추가
<br />
|}
===시작===
썸머노트 공식페이지에 설명되어 있다. https://summernote.org/getting-started/#for-bootstrap-4
역시, 공식사이트가 가장 적절하다.
글쓰기 환경에서만 작동하면 되니, 예시코드를 해석해 create.html 등에 두면 된다.
어려운 사람은 다음을 참고하자. 다음 코드가 <head>태그 안에 들어가게 하고..<syntaxhighlight lang="html+django">
    <meta charset="UTF-8">
    <title>Summernote with Bootstrap 4</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.js"></script>
</syntaxhighlight>다음을 폼 안의 적절한 장소에 기입하면 썸머노트 에디터를 볼 수 있다.(input으로 두면 안되고 textarea로 두어야 되더라;;)<syntaxhighlight lang="html+django">
<textarea name="content" id="summernote">
        {{ form.content.value|default_if_none:'' }}</textarea>
       
       
    <script>
      $('#summernote').summernote({
        placeholder: '여기에 내용 입력하세요~',
        tabsize: 2,
        height: 100
      });
    </script>
</syntaxhighlight>간단하게 넣을 수 있고, 반응형이다. 다만, 몇몇 tool이 안보인다.(가장 라이트한 형태로 보여진다. 기능이 없는 것은 아닌데, 툴바에 안보일 뿐.)
툴바를 어떻게 구성할지는 https://summernote.org/deep-dive/#initialization-options 에서 안내한다.
툴들을 묶는 이름은 style 등으로 제시하는데, 임의로 둘 수 있다.
영어긴 하지만 끝까지 읽어보면 기능이 정말 많다; 솔직히 좀 놀람;;;
===드롭다운 버튼 작동===
그런데, 위처럼 작성하면 드롭다운 버튼을 한 번 누르고 난 후에 다시 눌리지가 않는 기현상이 발생한다. 썸머노트의 구조적인 문제라고 하는데<ref>https://blog.naver.com/rainbow0043/221527367467</ref>, 다음의 한 줄을 썸머노트코드 마지막 줄에 추가하자.(부트스트랩의 popper를 설치했다면 문제 없음.)
<code>$('.dropdown-toggle').dropdown()</code>
===재미난 옵션===
{| class="wikitable"
|+
!
!
|-
|airMode: true,
|편집창 안에 입력하는 게 아니라, 텍스트를 블록선택하면 텍스트를 변경할 수 있게 하는 창이 뜬다.
|-
|lang: 'ko-KR',
|기본언어는 영어인데, 한글로 설정한다.(안되던데??)
|-
|fontNames:
|['Arial', 'Arial Black', 'Comic Sans MS', 'Courier New','맑은 고딕','궁서','굴림체','굴림','돋음체','바탕체'],
많은 글씨체를 지원한다. 그냥 위 목록에 추가하면 자동 추가됨.
|-
|defaultFontName:
|'돋음체',
기본 글씨체를 선택할 수 있다.(안되던데??)
|-
|maximumImageFileSize:
|최대그림 크기. 바이트 단위이다. 크기에 맞춰 단위를 변경해 표시해준다.
|}
===스크립트 예시===
나는 다음과 같은 형식을 선호한다.<syntaxhighlight lang="html+django">
<script>
      $('#summernote').summernote({
        placeholder: '여기에 내용 입력하세요~ 그림파일 용량은 2MB까지입니다~',
        tabsize: 2,
        height: 300, // 에디터 높이
        defaultFontName: '바탕체',
        toolbar: [
  ['style', ['style']],
  ['fontname', ['fontname']],
  ['fontsize', ['fontsize']],
  ['font style', ['bold', 'italic', 'underline','strikethrough', 'clear']],
  ['color', ['forecolor','color']],
  ['para', ['ul', 'ol', 'paragraph']],
  ['table', ['table']],
  ['insert', ['link', 'picture', 'video']],
  ['view', ['fullscreen', 'codeview', 'help']],
],
    defaultFontName:'바탕',
    fontNames: ['Arial', 'Comic Sans MS','맑은 고딕','궁서','굴림','돋음체','바탕'],
    fontSizes: ['8','9','10','11','12','14','16','18','20','22','24','28','30','36','50','72'],
    maximumImageFileSize:2097152,
  popover: {
                  image: [
                    ['image', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],
                    ['float', ['floatLeft', 'floatRight', 'floatNone']],
                    ['remove', ['removeMedia']]
                  ],
                  link: [
                    ['link', ['linkDialogShow', 'unlink']]
                  ],
                  table: [
                    ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],
                    ['delete', ['deleteRow', 'deleteCol', 'deleteTable']],
                  ],
                  air: [
                    ['color', ['color']],
                    ['font', ['bold', 'underline', 'clear']],
                    ['para', ['ul', 'paragraph']],
                    ['table', ['table']],
                    ['insert', ['link', 'picture']]
                  ]
                }
      });
$('.dropdown-toggle').dropdown()
    </script>
</syntaxhighlight>
===알면 좋을 사실===
이미지는 media가 아닌 DB에 저장하는듯.<references />

2022년 11월 28일 (월) 15:42 기준 최신판

장고! 웹 프레임워크! 틀:장고

  1. 장고:개요
  2. 장고:웹페이지설계
    1. 장고:앱
    2. 장고:url
    3. 장고:model
      1. 장고:DB
      2. 장고:모델 필드
      3. 장고:모델의 변경
    4. 장고:view
      1. 장고:클래스형 뷰, 제네릭 뷰
      2. 장고:view 각종 기능
    5. 장고:template
    6. 장고:static. 정적파일 사용하기
      1. 장고:CSS 사용하기
      2. 장고:JS 사용하기
      3. 장고:글꼴 사용
      4. 장고:부트스트랩
    7. 장고:media. 미디어 파일 사용하기
  3. 장고:관리자페이지
  4. 장고:settings.py
  5. 장고:기능구현
    1. 장고:회원관리
    2. 장고:유저
    3. 장고:커스텀 유저
    4. 장고:소셜로그인
    5. 장고:입력받기
    6. 장고:저장된 내용 활용하기
    7. 장고:변수 내보내기
    8. 장고:글쓰기
    9. 장고:페이징(페이지나누기)
    10. 장고:답변쓰기(댓글쓰기)
    11. 장고:추천,즐겨찾기
    12. 장고:새글(최신글) 나타내기
    13. 장고:썸머노트 설치
    14. 장고:네비게이션 바 만들기
    15. 장고:검색기능
    16. 장고:카테고리 만들기
    17. 장고:사진 올리기
    18. 장고:파일 업로드
    19. 장고:이메일app 만들기
    20. 장고:매직 그리드
  6. 장고:웹서비스
    1. 장고:Git
    2. 장고:리눅스에 올리기
    3. 장고:우분투에 올리기(nginx 사용)
    4. 장고:도커로 올리기
  7. 장고:팁

개요[편집 | 원본 편집]

WYSIWYG[편집 | 원본 편집]

위징위그. What You See Is What You Get 의 약자이다. 일반적으로 입력을 하면 코드를 사용하여 입력을 해야 사용자가 원하는 크기, 색의 글을 쓸 수 있다. 제대로 된 게시판, 사용자 친화적인 게시판이 되기 위해선 필수적인 기능이다.

네이버 스마트에디터, MediumEditor, 섬머노트 등이 오픈되어있다.


일반적인 textarea에서 표현할 수 있는 방식은 굉장히 적다. 적어도 위키처럼 목차관리를 해준다든가, 링크를 만든다든가 정도는 되야 하지 않을까. 많이 사용되는 에디터인 섬머노트를 장고에 설치해본다.

이미 장고앱으로 개발되어 있어 쉽게 설치가 가능하다.

django-summernote 모듈로 설치하는 방법[편집 | 원본 편집]

이 방법보다 부트스트랩 위에 올리는 방법이 더 괜찮다;;(2022.05기준 반응형으로 넣기 어렵다.) 이 방법은 쓰지 말자.

과정 설명
pip install django-summernote 장고에서 사용하는 썸머노트를 설치.
settings.py의 APP 등록 'django_summernote', 추가
settings.py 설정 이미지 업로드를 위해

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

추가

settings.py 설정 클릭재킹 방지설정 변경.

'django.middleware.clickjacking.XFrameOptionsMiddleware'라는 미들웨어가 클릭재킹을 방지해주는데, 기본설정이 DENY다.

때문에 아래 옵션을 주어 설정을 변경해준다.
#클릭재킹 방지설정 변경
X_FRAME_OPTIONS = 'SAMEORIGIN'

urls.py 변경 루트 urls.py에 다음의 코드를 추가한다.

path('summernote/', include('django_summernote.urls')),

모델 만들기 기존에 사용하던 모델이 있다면 굳이 만들 필요는 없겠다.
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=10)
    content = models.TextField()

    def __str__(self):
        return self.title
폼 만들기 기존에 사용하던 폼이 있다면 내용을 추가해주면 된다.
from django import forms
from .models import Post

from django_summernote.widgets import SummernoteWidget

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['title', 'content']
        widgets = {'content': SummernoteWidget(),}
폼까지 완성했으면 기존의 탬플릿이 잘 작동하나 확인해본다.

혹시나 {{

탬플릿 변경 썸머노트로 입력한 내용은 html코드로 나온다. 탬플릿 필터 |safe 를 사용하여 detail.html의 콘텐츠 부분을 다음과 같이 수정한다.
<div class="card-text" style="white-space: pre-line;">{{ question.content| safe  }}</div>

근데, 이 섬머노트는 반응형이 아니다; 반영할 수 있는 방법이 있을까?


부트스트랩 위에 올리기[편집 | 원본 편집]

시작 전에[편집 | 원본 편집]

미디어 설정을 해주는데... 확인이 필요하다. summernote에선 DB에 바로 저장해버리는듯.

settings.py 설정 이미지 업로드를 위해

MEDIA_URL = '/media/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

추가


시작[편집 | 원본 편집]

썸머노트 공식페이지에 설명되어 있다. https://summernote.org/getting-started/#for-bootstrap-4

역시, 공식사이트가 가장 적절하다.

글쓰기 환경에서만 작동하면 되니, 예시코드를 해석해 create.html 등에 두면 된다.

어려운 사람은 다음을 참고하자. 다음 코드가 <head>태그 안에 들어가게 하고..

    <meta charset="UTF-8">
    <title>Summernote with Bootstrap 4</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.js"></script>

다음을 폼 안의 적절한 장소에 기입하면 썸머노트 에디터를 볼 수 있다.(input으로 두면 안되고 textarea로 두어야 되더라;;)

<textarea name="content" id="summernote">
        {{ form.content.value|default_if_none:'' }}</textarea>
        
        
    <script>
      $('#summernote').summernote({
        placeholder: '여기에 내용 입력하세요~',
        tabsize: 2,
        height: 100
      });
    </script>

간단하게 넣을 수 있고, 반응형이다. 다만, 몇몇 tool이 안보인다.(가장 라이트한 형태로 보여진다. 기능이 없는 것은 아닌데, 툴바에 안보일 뿐.)

툴바를 어떻게 구성할지는 https://summernote.org/deep-dive/#initialization-options 에서 안내한다.

툴들을 묶는 이름은 style 등으로 제시하는데, 임의로 둘 수 있다.

영어긴 하지만 끝까지 읽어보면 기능이 정말 많다; 솔직히 좀 놀람;;;

드롭다운 버튼 작동[편집 | 원본 편집]

그런데, 위처럼 작성하면 드롭다운 버튼을 한 번 누르고 난 후에 다시 눌리지가 않는 기현상이 발생한다. 썸머노트의 구조적인 문제라고 하는데[1], 다음의 한 줄을 썸머노트코드 마지막 줄에 추가하자.(부트스트랩의 popper를 설치했다면 문제 없음.)

$('.dropdown-toggle').dropdown()

재미난 옵션[편집 | 원본 편집]

airMode: true, 편집창 안에 입력하는 게 아니라, 텍스트를 블록선택하면 텍스트를 변경할 수 있게 하는 창이 뜬다.
lang: 'ko-KR', 기본언어는 영어인데, 한글로 설정한다.(안되던데??)
fontNames: ['Arial', 'Arial Black', 'Comic Sans MS', 'Courier New','맑은 고딕','궁서','굴림체','굴림','돋음체','바탕체'],

많은 글씨체를 지원한다. 그냥 위 목록에 추가하면 자동 추가됨.

defaultFontName: '돋음체',

기본 글씨체를 선택할 수 있다.(안되던데??)

maximumImageFileSize: 최대그림 크기. 바이트 단위이다. 크기에 맞춰 단위를 변경해 표시해준다.

스크립트 예시[편집 | 원본 편집]

나는 다음과 같은 형식을 선호한다.

<script>
      $('#summernote').summernote({
        placeholder: '여기에 내용 입력하세요~ 그림파일 용량은 2MB까지입니다~',
        tabsize: 2,
        height: 300, // 에디터 높이
        defaultFontName: '바탕체',
        toolbar: [
  ['style', ['style']],
  ['fontname', ['fontname']],
  ['fontsize', ['fontsize']],
  ['font style', ['bold', 'italic', 'underline','strikethrough', 'clear']],
  ['color', ['forecolor','color']],
  ['para', ['ul', 'ol', 'paragraph']],
  ['table', ['table']],
  ['insert', ['link', 'picture', 'video']],
  ['view', ['fullscreen', 'codeview', 'help']],
],
    defaultFontName:'바탕',
    fontNames: ['Arial', 'Comic Sans MS','맑은 고딕','궁서','굴림','돋음체','바탕'],
    fontSizes: ['8','9','10','11','12','14','16','18','20','22','24','28','30','36','50','72'],
    maximumImageFileSize:2097152,

  popover: {
                  image: [
                    ['image', ['resizeFull', 'resizeHalf', 'resizeQuarter', 'resizeNone']],
                    ['float', ['floatLeft', 'floatRight', 'floatNone']],
                    ['remove', ['removeMedia']]
                  ],
                  link: [
                    ['link', ['linkDialogShow', 'unlink']]
                  ],
                  table: [
                    ['add', ['addRowDown', 'addRowUp', 'addColLeft', 'addColRight']],
                    ['delete', ['deleteRow', 'deleteCol', 'deleteTable']],
                  ],
                  air: [
                    ['color', ['color']],
                    ['font', ['bold', 'underline', 'clear']],
                    ['para', ['ul', 'paragraph']],
                    ['table', ['table']],
                    ['insert', ['link', 'picture']]
                  ]
                }
      });
$('.dropdown-toggle').dropdown()
    </script>

알면 좋을 사실[편집 | 원본 편집]

이미지는 media가 아닌 DB에 저장하는듯.