在技術博客文章詳情頁面中,最受程序員歡迎的便捷簡約排版方式莫屬Markdown,本文主要介紹Markdown格式在博文的前端顯示及代碼高亮,和Django後臺admin中編輯博文時Markdown的實時預覽。javascript
Markdown是一種輕量級的標記語言,它容許人們「使用易讀易寫的純文本格式編寫文檔,而後轉換成有效的或者HTML文檔。關於 Markdown語法看這裏。 Python插件markdown默認支持標準的markdown語法,但標準語法裏代碼塊須要每行前空4個空格才能識別。推薦使用 Python-markdown2 ,它是python-markdown的升級版,支持GFM式(GFM 是 Github 拓展的基於 Markdown 的一種純文本的書寫格式)的markdown書寫格式。容許使用```
包裹代碼塊。css
打開CMD,進入虛擬環境html
pip install 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
中包括了縮寫、表格、語法高亮、自動生成目錄等擴展。 而後,修改前端模板有關文章正文的部分:java
#templates/article.html # 在 article.body 後加上 |safe 過濾器 <p>{{ article.body|safe }}</p>
safe 是 Django 模板系統中的過濾器(Filter),Django出於安全的考慮,會將輸出的HTML代碼進行轉義,這使得article.body中渲染的HTML文本沒法正常顯示。而|safe就相似給article.body貼了一個標籤,表示這一段字符不須要進行轉義了。 啓動服務器,在後臺中新錄入一條用markdown語法書寫的文章,內容以下:python
# 國風·周南·關雎 --- **關關雎鳩,在河之洲。窈窕淑女,君子好逑。** 參差荇菜,左右流之。窈窕淑女,寤寐求之。 --- + 列表一 + 列表二 + 列表二-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的原生格式了,但後續須要代碼高亮及其格式的美化。git
Pygments是一種通用語法高亮顯示器,能夠幫助咱們自動生成美化代碼塊的樣式文件。(插件highlight.js也比較經常使用) 從新打開命令行窗口,進入虛擬環境安裝Pygments:程序員
pip install Pygments
安裝完成後Pygments在後臺爲咱們作了不少事,它把高亮的一些語法轉爲css樣式,把代碼分紅了一個一個單詞,在前端頁面,直接右鍵查看源碼就能看到了。須要注意的是爲了讓Pygments正確識別分割代碼塊,在後臺編輯輸入代碼塊時,建議在```包裹後加上代碼種類,以下:github
···Python 代碼塊 ···
而後咱們須要生成高亮樣式,在命令行中進入static目錄中的css文件中,輸入Pygments指令後回車:數據庫
pygmentize -S default -f html -a .codehilite > default.css
-a .codehilite
指全部css選擇器都具備.codehilite這一優先選擇器-S default
就是指定所須要的樣式,Pygments還內置了不少其餘的樣式, 官網樣式> 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>
在使用markdown的步驟中,咱們在 Storm / views.py 函數中的markdown.extensions.extra
參數中加入了自動生成目錄插件,在輸入博文時,在須要加入標題的位置加入[TOC]
標記便可,在前端文章中就能 看到[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>
在django中有很好的插件來讓咱們快速完成 django admin 後臺中博文的編輯及實時預覽—django-mdeditor
打開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
運行項目,進入後臺admin,進入博文的編輯頁面,編輯Markdown及實時預覽。 最後的問題就是如何作到Django admin中的預覽效果與前端一致,由於咱們的樣式配置不一樣,Django插件mdeditor的Markdown樣式位置通常在虛擬環境下的 Lib\site-packages\mdeditor\static\mdeditor\css 中的editormd.css裏,能夠修改爲前端的樣式文件,或者將前端引入這個樣式,並在文章包裹的標籤中加入class="markdown-body"