Django從零搭建個人博客 | 使用Markdown語法書寫文章整合


原文章地址: EOSONES博客

在技術博客文章詳情頁面中,最受程序員歡迎的便捷簡約排版方式莫屬Markdown,本文主要介紹Markdown格式在博文的前端顯示及代碼高亮,和Django后台admin中編輯博文時Markdown的實時預覽。

前端顯示

1、安裝Markdown

Markdown是一種輕量級的標記語言,它允許人們“使用易讀易寫的純文本格式編寫文檔,然后轉換成有效的或者HTML文檔。關於 Markdown語法看這里。
Python插件markdown默認支持標准的markdown語法,但標准語法里代碼塊需要每行前空4個空格才能識別。推薦使用 Python-markdown2 ,它是python-markdown的升級版,支持GFM式(GFM 是 Github 拓展的基於 Markdown 的一種純文本的書寫格式)的markdown書寫格式。允許使用```包裹代碼塊。

打開CMD,進入虛擬環境

pip install markdown

2、使用Markdown

為了將Markdown語法書寫的文章渲染為HTML文本,首先改寫 Storm / views.py 的 文章處理類 ArticleDetailView:

#Storm / views.py 

from Storm import models
from django.shortcuts import render, get_object_or_404
from django.views.generic import DetailView #從數據庫獲取模型的一條記錄數據DetailView
import markdown #導入markdown
from django.utils.text import slugify
from markdown.extensions.toc import TocExtension

#文章詳情頁類處理
class ArticleDetailView(DetailView):
    model=models.Article
    template_name = 'article.html' 
    context_object_name = 'article' 

    def get(self, request, *args, **kwargs):
       # ···

    def get_object(self, queryset=None):
    # 覆寫 get_object 方法的目的是因為需要對 article 的 body 值進行渲染
    # 將markdown語法渲染成html樣式
    article.body = markdown.markdown(article.body,
        extensions=[
        # 包含 縮寫、表格等常用擴展
        'markdown.extensions.extra',
        # 語法高亮擴展
        'markdown.extensions.codehilite',
        #允許我們自動生成目錄
         'markdown.extensions.toc',
        ])
    return article

代碼中markdown.markdown語法接收兩個參數:第一個參數是需要渲染的文章正文article.body;第二個參數載入了常用的語法擴展,markdown.extensions.extra中包括了縮寫、表格、語法高亮、自動生成目錄等擴展。
然后,修改前端模板有關文章正文的部分:

#templates/article.html

# 在 article.body 后加上 |safe 過濾器
<p>{{ article.body|safe }}</p>

safe 是 Django 模板系統中的過濾器(Filter),Django出於安全的考慮,會將輸出的HTML代碼進行轉義,這使得article.body中渲染的HTML文本無法正常顯示。而|safe就類似給article.body貼了一個標簽,表示這一段字符不需要進行轉義了。
啟動服務器,在后台中新錄入一條用markdown語法書寫的文章,內容如下:

# 國風·周南·關雎
---
**關關雎鳩,在河之洲。窈窕淑女,君子好逑。**

參差荇菜,左右流之。窈窕淑女,寤寐求之。

---
+ 列表一
+ 列表二
    + 列表二-1
    + 列表二-2
---

···
def detail(request, id):
 article = ArticlePost.objects.get(id=id)
 # 將markdown語法渲染成html樣式
 article.body = markdown.markdown(article.body,
  extensions=[
      # 包含 縮寫、表格等常用擴展
     'markdown.extensions.extra',
      # 語法高亮擴展
      'markdown.extensions.codehilite',
      #允許我們自動生成目錄
       'markdown.extensions.toc',
  ])
 context = { 'article': article }
 return render(request, 'article/detail.html', context)
···

此時可以解析出Markdown的原生格式了,但后續需要代碼高亮及其格式的美化。

3、代碼高亮

Pygments是一種通用語法高亮顯示器,可以幫助我們自動生成美化代碼塊的樣式文件。(插件highlight.js也比較常用)
重新打開命令行窗口,進入虛擬環境安裝Pygments:

pip install Pygments

安裝完成后Pygments在后台為我們做了很多事,它把高亮的一些語法轉為css樣式,把代碼分成了一個一個單詞,在前端頁面,直接右鍵查看源碼就能看到了。需要注意的是為了讓Pygments正確識別分割代碼塊,在后台編輯輸入代碼塊時,建議在```包裹后加上代碼種類,如下:

···Python
   代碼塊
···

然后我們需要生成高亮樣式,在命令行中進入static目錄中的css文件中,輸入Pygments指令后回車:

pygmentize -S default -f html -a .codehilite > default.css
  1. -a .codehilite指所有css選擇器都具有.codehilite這一優先選擇器
  2. -S default就是指定所需要的樣式,Pygments還內置了很多其他的樣式, 官網樣式
  3. > default.css將內容輸出到default.css文件中
    這里有一點需要注意, 生成命令中的 -a 參數需要與真實頁面中的 CSS Selector 相對應,即.codehilite這個字段在有些版本中應寫為.highlight。如果后面的代碼高亮無效,很可能是這里出了問題。
    此時在css目錄中是否自動生成了一個叫default.css的文件,接下來我們在 content-base.html 中引用這個文件,同時引入bootstrapc框架會使排版格式更加美觀。
#templates/content-base.html
  <head>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <!-- 引入monikai.css -->
    <link rel="stylesheet" href="{% static 'css/default.css' %}">
  </head>

完成以上步驟后先退出服務器然后重新 runserver,順利的話看到如下:

最后,還可以對markdown文本的整體樣式進行自定義修改,為了不影響頁面其他地方,最好在包裹文章的標簽中加個class標識。

#例如修改代碼框

.markdown pre {
    padding: 1em;
    border: none;
    line-height: 1.45;
    max-height: 35em;
    position: relative;
    background: url(/static/images/blueprint.png) #F6F6F6;
}
#...
<p class=‘markdown’>{{ article.body|safe }}</p>

4、自動生成文章目錄

在使用markdown的步驟中,我們在 Storm / views.py 函數中的markdown.extensions.extra參數中加入了自動生成目錄插件,在輸入博文時,在需要加入標題的位置加入[TOC]標記即可,在前端文章中就能 看到[TOC]標記的地方被內容的目錄替換了。
上述方式的一個局限局限性就是只能通過

#Storm/views.py

from Storm import models
from django.shortcuts import render, get_object_or_404
from django.views.generic import DetailView #從數據庫獲取模型的一條記錄數據DetailView
import markdown #導入markdown
from django.utils.text import slugify
from markdown.extensions.toc import TocExtension

#文章詳情頁類處理
class ArticleDetailView(DetailView):
    model=models.Article
    template_name = 'article.html' 
    context_object_name = 'article' 

    def get(self, request, *args, **kwargs):
       # ···

    def get_object(self, queryset=None):
      # 覆寫 get_object 方法的目的是因為需要對 article 的 body 值進行渲染,用model的方法
      article = super(ArticleDetailView, self).get_object(queryset=None)
      md = markdown.Markdown(extensions=[
            'markdown.extensions.extra',
            'markdown.extensions.codehilite',
            #美化點擊目錄時的url顯示模塊
            TocExtension(slugify=slugify),
       ])
       #md實例的convert方法將markdown轉為html
       article.body = md.convert(article.body)
       #實例 md 就會多出一個 toc 屬性
       article.toc = md.toc
       return article

注意文章 article 實例本身是沒有 md 屬性的,利用動態語言的特性我們給它動態添加了 md 屬性。此時在前端模板的任何位置就可以進行渲染目錄。

 <div>
    <p>目錄</p>
    {{ article.toc|safe }}
    <a href="javascript:void(0);" class="top">返回頂部</a>
 </div>

Admin中編輯及預覽

在django中有很好的插件來讓我們快速完成 django admin 后台中博文的編輯及實時預覽—django-mdeditor

1、安裝配置

打開CMD,進入虛擬環境

pip install django-mdeditor

在項目的settings.py的INSTALLED_APPS中添加’mdeditor’,

INSTALLED_APPS = [
    #...
    "mdeditor",
    #...
]

配置好上傳目錄media文件夾

#Myblog/settings.py

# 媒體文件專屬參數設置(需要加url識別才能訪問)
MEDIA_URL = "/media/" # 媒體文件別名(相對路徑) 和 絕對路徑
MEDIA_ROOT = (
    os.path.join(BASE_DIR, 'media')
)

最后將mdeditor添加到項目的url中:

#Myblog/urls.py

urlpatterns = [
    #...
    re_path(r'mdeditor/', include('mdeditor.urls')),
]

在我們的 Storm/models.py 下的文章模型中重寫 body 字段

from mdeditor.fields import MDTextField

# 文章
class Article(models.Model):
    #...
    # 文章內容
    body = MDTextField(verbose_name='文章內容')
    #...

注意在 Storm/admin.py 中配置以便后台顯示 ,然后遷移數據庫

python manage.py makemigrations
python manage.py migrate

2、查看效果

運行項目,進入后台admin,進入博文的編輯頁面,編輯Markdown及實時預覽。

最后的問題就是如何做到Django admin中的預覽效果與前端一致,因為我們的樣式配置不同,Django插件mdeditor的Markdown樣式位置一般在虛擬環境下的 Lib\site-packages\mdeditor\static\mdeditor\css 中的editormd.css里,可以修改成前端的樣式文件,或者將前端引入這個樣式,並在文章包裹的標簽中加入class="markdown-body"

參考:追夢任務 | Markdown 自動生成文章目錄 | Django搭建個人博客:使用Markdown語法書寫文章


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM