마크다운 적용하기

Posted on 2021-08-25 by GKSRUDTN99
Django로 웹사이트 만들기 장고

django-markdownx로 마크다운 문법 적용하기

django-markdownx 설치하기

1. pip install django-markdownx로 설치한다.

2. INSTALLED_APPS에 markdownx를 추가한다.

3. urls.py에 path('markdownx/', include('markdownx.urls'))를 추가한다.

4. Post 모델의 content 필드를 TextField가 아닌 MarkdownxField로 변경한다.

5. 마이그레이션

post_form, post_update_form 수정하기

{{ form.media }} 추가

<!-- post_form.html -->
{% extends 'blog/base_full_width.html' %}
{% load crispy_forms_tags %}
{% block head_title %}Create Post - Blog{% endblock %}


{% block main_area %}
    <h1>Create New Post</h1>
    <hr/>
    <form method="post" enctype="multipart/form-data">
        {% csrf_token %}
            {{ form | crispy}}
            <div id="div_id_tags_str">
                <label for="id_tags_str">Tags:</label>
                <input type="text" name="tags_str" id="id_tags_str" class="textinput textInput form-control">
            </div>
        <br />
        <button type="submit" class="btn btn-primary float-end">Submit</button>
    </form>
    {{ form.media }}
{% endblock %}

post_update_form도 동일하게 수정한다.

작성한 내용이 마크다운으로 보이도록 get_content_markdown() 메서드 만들기

models.py에서 makrdownx에서 makrdownify를 import하고, get_content_markdown()을 만든다.

이 메서드는 Post 레코드의 content 필드에 저장되어 있는 텍스트를 마크다운 문법을 적용해 HTML로 만든다.

# models.py
class Post(models.Model):
    (... 생략 ...)
    def get_content_markdown(self):
        return markdownify(self.content)

post_detail.html에 get_content_markdown 이용하도록 수정하기.

<!-- post_detail.html
<!-- Post content-->
        <section class="mb-5">
            <p>{{ post.get_content_markdown | safe }}</p>

post_list.html도 마찬가지로 수정하기

이전과 달리 정보가 HTML로 넘어오기 때문에 truncatewords를 truncatewords_html로 수정한다.

<!-- post_list.html -->
<div class="card-body">
                    <div class="small text-muted">
                        Posted on {{ p.created_at }} by
                        <a href="#">{{ p.author | upper }}</a>
                        {% if p.category %}
                            <span class="badge bg-secondary float-end">{{ p.category }}</span>
                        {% else %}
                            <span class="badge bg-secondary float-end">미분류</span>
                        {% endif %}
                    </div>
                    <h2 class="card-title">{{ p.title }}</h2>
                    {% if p.hook_text %}
                        <h5 class="text-muted">{{ p.hook_text }}</h5>
                    {% endif %}
                    <p class="card-text">{{ p.get_content_markdown | truncatewords_html:45 | safe}}</p>
                    {% if p.tags.exists %}
                        <i class="fas fa-tags"></i>
                        {% for tag in p.tags.all %}
                            <a href="{{ tag.get_absolute_url }}"><span class="badge bg-secondary">{{ tag }}</span></a>
                        {% endfor %}
                        <br/>
                        <br/>
                    {% endif %}

관리자 페이지에서도 마크다운을 활용할 수 있도록 수정하기.

MarkdownxModel Admin을 임포트하고 admin.site.register(Post)를 수정한다.

admin.site.register(Post, MarkdownxModelAdmin)

여러 줄에 걸친 코드블럭을 사용하거나, 언어에 따른 code 하이라이트 기능을 사용하기 위해선 추가적인 설정이 필요하다.

1. 하이라이트 기능을 사용하기 위해 pygments를 설치한다.

pip install pygments

2. settings.py에 다음 설정을 추가한다.

fenced_code는 여러 줄에 걸친 코드블럭을 위한 설정이고,
codehilite는 code 하이라이트 기능을 위한 설정이다. 이 설정은 pygments를 필요로 한다..

MARKDOWNX_MARKDOWN_EXTENSIONS = [
    'markdown.extensions.codehilite',
    'markdown.extensions.fenced_code',
    'markdown.extensions.extra',
    'markdown.extensions.toc'
]

MARKDOWNX_MARKDOWN_EXTENSION_CONFIGS = {
    'markdown.extensions.codehilite': {
        'use_pygments': True,
        'noclasses': True
    }
}