Django 博客開發教程 9 - 支持 Markdown 語法和代碼高亮
為了讓博客文章具有良好的排版,顯示更加豐富的格式,我們使用 Markdown 語法來書寫我們的博文。Markdown 是一種 HTML 文本標記語言,隻要遵循它約定的語法格式,Markdown 的渲染器就能夠把我們寫的文章轉換為標準的 HTML 文檔,從而讓我們的文章呈現更加豐富的格式,例如標題、列表、代碼塊等等 HTML 元素。由於 Markdown 語法簡單直觀,不用超過 5 分鍾就可以掌握常用的標記語法,因此大家青睞使用 Markdown 書寫 HTML 文檔。下麵讓我們的博客也支持使用 Markdown 書寫。
安裝 Python Markdown
將 Markdown 格式的文本渲染成標準的 HTML 文檔是一個複雜的工作,好在已有好心人幫我們完成了這些工作,我們直接使用即可。首先安裝 Markdown,這是一個 Python 第三方庫,**激活虛擬環境**,然後使用命令 pip install markdown
安裝即可。
在 detail 視圖中渲染 Markdown
將 Markdown 格式的文本渲染成 HTML 文本非常簡單,隻需調用這個庫的 markdown
方法即可。我們書寫的博客文章內容存在 Post
的 body
屬性裏,回到我們的詳情頁視圖函數,對 post
的 body
的值做一下渲染,把 Markdown 文本轉為 HTML 文本再傳遞給模板:
blog/views.py
import markdown
from django.shortcuts import render, get_object_or_404
from .models import Post
def detail(request, pk):
post = get_object_or_404(Post, pk=pk)
# 記得在頂部引入 markdown 模塊
post.body = markdown.markdown(post.body,
extensions=[
'markdown.extensions.extra',
'markdown.extensions.codehilite',
'markdown.extensions.toc',
])
return render(request, 'blog/detail.html', context={'post': post})
這樣我們在模板中展示 {{ post.body }} 的時候,就不再是原始的 Markdown 文本了,而是渲染過後的 HTML 文本。注意這裏我們給 markdown
渲染函數傳遞了額外的參數 extensions
,它是對 Markdown 語法的拓展,這裏我們使用了三個拓展,分別是 extra、codehilite、toc。extra 本身包含很多拓展,而 codehilite 是語法高亮拓展,這為我們後麵的實現代碼高亮功能提供基礎,而 toc 則允許我們自動生成目錄(在以後會介紹)。
來測試一下效果,進入後台,這次我們發布一篇用 Markdown 語法寫的測試文章看看,你可以使用以下的 Markdown 測試代碼進行測試,也可以自己書寫你喜歡的 Markdown 文本。假設你是 Markdown 新手參考一下這些教程,一定學一下,保證你可以在 5 分鍾內掌握常用的語法格式,而以後對你寫作受用無窮。可謂充電五分鍾,通話 2 小時。以下是我學習中的一些參考資料:
# 一級標題
## 二級標題
### 三級標題
- 列表項1
- 列表項2
- 列表項3
> 這是一段引用
```python
def detail(request, pk):
post = get_object_or_404(Post, pk=pk)
post.body = markdown.markdown(post.body,
extensions=[
'markdown.extensions.extra',
'markdown.extensions.codehilite',
'markdown.extensions.toc',
])
return render(request, 'blog/detail.html', context={'post': post})
```
如果你發現無法顯示代碼塊,即代碼無法換行,請檢查代碼塊的語法是否書寫有誤。代碼塊的語法如上邊的測試文本中最後一段所示。
你可能想在文章中插入圖片,目前能做的且推薦做的是使用外鏈引入圖片。比如將圖片上傳到七牛雲這樣的雲存儲服務器,然後通過 Markdown 的圖片語法將圖片引入。Markdown 引入圖片的語法為:
。
safe 標簽
我們在發布的文章詳情頁沒有看到預期的效果,而是類似於一堆亂碼一樣的 HTML 標簽,這些標簽本應該在瀏覽器顯示它本身的格式,但是 Django 出於安全方麵的考慮,任何的 HTML 代碼在 Django 的模板中都會被轉義(即顯示原始的 HTML 代碼,而不是經瀏覽器渲染後的格式)。為了解除轉義,隻需在模板標簽使用 safe
過濾器即可,告訴 Django,這段文本是安全的,你什麼也不用做。在模板中找到展示博客文章主體的 {{ post.body }} 部分,為其加上 safe 過濾器,{{ post.body|safe }},大功告成,這下看到預期效果了。
safe 是 Django 模板係統中的過濾器(Filter),可以簡單地把它看成是一種函數,其作用是作用於模板變量,將模板變量的值變為經過濾器處理過後的值。例如這裏 {{ post.body|safe }},本來 {{ post.body }} 經模板係統渲染後應該顯示 body 本身的值,但是在後麵加上 safe 過濾器後,渲染的值不再是body 本身的值,而是由 safe 函數處理後返回的值。過濾器的用法是在模板變量後加一個 | 管道符號,再加上過濾器的名稱。可以連續使用多個過濾器,例如 {{ var|filter1|filter2 }}。
代碼高亮
程序員寫博客免不了要插入一些代碼,Markdown 的語法使我們容易地書寫代碼塊,但是目前來說,顯示的代碼塊裏的代碼沒有任何顏色,很不美觀,也難以閱讀,要是能夠像我們的編輯器裏一樣讓代碼高亮就好了。雖然我們在渲染時使用了 codehilite 拓展,但這隻是實現代碼高亮的第一步,還需要簡單的幾步才能達到我們的最終目的。
安裝 Pygments
首先我們需要安裝 Pygments,**激活虛擬環境**,運行: pip install Pygments
安裝即可。
搞定了,雖然我們除了安裝了一下 Pygments 什麼也沒做,但 Markdown 使用 Pygments 在後台為我們做了很多事。如果你打開博客詳情頁,找到一段代碼段,在瀏覽器查看這段代碼段的 HTML 源代碼,可以發現 Pygments 的工作原理是把代碼切分成一個個單詞,然後為這些單詞添加 css 樣式,不同的詞應用不同的樣式,這樣就實現了代碼顏色的區分,即高亮了語法。為此,還差最後一步,引入一個樣式文件來給這些被添加了樣式的單詞定義顏色。
引入樣式文件
在項目的 blog\static\blog\css\highlights\ 目錄下應該能看到很多 .css 樣式文件,這些文件是用來提供代碼高亮樣式的。選擇一個你喜歡的樣式文件,在 base.html 引入即可(別忘了使用 static 模板標簽)。比如我比較喜歡 github.css 的樣式,那麼引入這個文件:
templates/base.html
...
<link rel="stylesheet" href="{% static 'blog/css/pace.css' %}">
<link rel="stylesheet" href="{% static 'blog/css/custom.css' %}">
...
+ <link rel="stylesheet" href="{% static 'blog/css/highlights/github.css' %}">
這裏 + 號表示添加這行代碼。好了,看看效果,大功告成,終於可以愉快地貼代碼了。
注意:如果你按照教程中的方法做完後發現代碼依然沒有高亮,請依次檢查以下步驟:
- 確保在渲染文本時添加了
markdown.extensions.codehilite
拓展,詳情見上文。 - 確保安裝了 Pygments。
- 確保代碼塊的 Markdown 語法正確,**特別是指明該代碼塊的語言類型**,具體請參見上文中 Markdown 的語法示例。
- 在瀏覽器端代碼塊的源代碼,看代碼是否被 pre 標簽包裹,並且代碼的每一個單詞都被 span 標簽包裹,且有一個 class 屬性值。如果沒有,極有可能是前三步中某個地方出了問題。
- 確保用於代碼高亮的樣式文件被正確地引入,具體請參見上文中引入樣式文件的講解。
- 有些樣式文件可能對代碼高亮沒有作用,首先嚐試用 github.css 樣式文件做測試。
總結
本章節的代碼位於:Step9: markdown and code highlight supported。
如果遇到問題,請通過下麵的方式尋求幫助。
- 在 支持 Markdown 語法和代碼高亮 - 追夢人物的博客 的評論區留言。
- 將問題的詳細描述通過郵件發送到 djangostudyteam@163.com,一般會在 24 小時內回複。
更多Django 教程,請訪問 追夢人物的博客。
最後更新:2017-05-31 12:02:41