10. 支持 markdown 語法和代碼高亮

本教程內容已過時菩浙,更新版教程請訪問: Django 博客開發(fā)入門教程

這是 Django 博客教程的第 10 篇,在閱讀此篇教程以前喳钟,請確保你已閱讀 Django 博客教程的前 9 篇:
1. Django 博客教程:前言
2. 搭建開發(fā)環(huán)境
3. 建立我們的 django 博客應用
4. 創(chuàng)建 django 博客的數據庫模型
5. 讓 django 完成翻譯——遷移數據庫模型
6. django 博客首頁視圖
7. 真正的 django 博客首頁視圖
8. 在 django admin 后臺發(fā)布我們的文章
9. 博客文章詳情頁

為了讓博客文章具有良好的排版屁使,顯示更加豐富的格式,我們使用 markdown 語法來書寫我們的博文奔则。markdown 是一種 html 文本標記語言蛮寂,只要遵循它約定的語法格式,markdown 的渲染器就能夠把我們寫的文章轉換為標準的 html 文檔易茬,從而讓我們的文章呈現更加豐富的格式酬蹋,例如標題、列表抽莱、代碼塊等等 html 元素范抓。由于 markdown 語法簡單直觀,不用超過 5 分鐘就可以掌握常用的標記語法食铐,這就是大家青睞使用 markdown 書寫 html 文檔的原因匕垫。下面讓我們的博客也支持使用 markdown 書寫。

將 markdown 格式的文本渲染成標準的 html 文檔是一個復雜的工作璃岳,好在已有好心人寫好了年缎,我們直接使用即可。首先安裝 markdown铃慷,這是一個 Python 第三方庫单芜,進入虛擬環(huán)境,然后 pip install markdown 安裝即可犁柜。

將 markdown 格式的文本渲染成 html 文本非常簡單洲鸠,只需調用這個庫的 markdown 方法即可。我們書寫的內容存在 Post 的 body 屬性里馋缅,回到我們的詳情頁視圖函數扒腕,對獲取的 post 的 body 的值做一下渲染,把 markdown 文本轉為 html 文本再傳遞給模板:

blog/details.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)
    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 則允許我們自動生成目錄凳厢。

來測試一下效果账胧,進入后臺竞慢,這次我們發(fā)布一篇 markdown 語法的測試文章看看,你可以使用以下的 markdown 測試代碼進行測試治泥,也可以自己書寫你喜歡的 markdown 文本梗顺。假設你是 markdown 新手參考一下這些教程,一定學一下车摄,保證你可以在 5 分鐘內掌握常用的語法格式,而以后對你寫作受用無窮仑鸥∷辈ィ可謂充電五分鐘,通話 2 小時眼俊。以下是我學習中的一些參考資料:

Markdown——入門指南

Markdown 語法說明 (簡體中文版)

# 一級標題

## 二級標題

### 三級標題

- 列表項1
- 列表項2
- 列表項3

> 這是一段引用

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

?```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})
?```

## html safe 標簽的使用意狠。

我們在發(fā)布的文章詳情頁沒有看到預期的效果,而是類似于一堆亂碼一樣的 html 標簽疮胖,這些標簽本應該在瀏覽器顯示它本身的格式环戈,但是 django 出于安全方面的考慮,任何的 html 代碼在 django 的模板中都會被轉義(即輸入原始的 html 文檔代碼澎灸,而不是經瀏覽器渲染后的格式)院塞,為了解除轉義,只需在模板標簽使用 safe 過濾器即可性昭,告訴 django拦止,這段文本是安全的,你什么也不用做糜颠。在模板中找到展示博客文章主體的 {{ post.body }} 部分汹族,為其加上 safe 過濾器,{{ post.body|safe }}其兴,大功告成顶瞒,這下看到預期效果了。

![](http://upload-images.jianshu.io/upload_images/1008138-ec21a310f98cb005.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 代碼高亮

程序員寫博客免不了要插入一些代碼元旬,markdown 的語法使我們容易地書寫代碼塊榴徐,但是目前來說,顯示的代碼塊里的代碼沒有任何顏色法绵,很不美觀箕速,也難以閱讀,要是能夠像我們的編輯器里一樣讓代碼高亮就好了朋譬。雖然我們在渲染時使用了 codehilite 拓展盐茎,但這只是實現代碼高亮的第一步,還需要簡單的幾步才能達到我們的最終目的徙赢。

首先我們需要安裝 Pygments字柠,進入虛擬環(huán)境探越,運行: `pip install Pygments`

搞定了,雖然我們除了安裝了一下 Pygments 什么也沒做窑业,但 Markdown 使用 Pygments 在后臺為我們做了很多事钦幔。如果你打開博客詳情頁,找到一段代碼段常柄,在瀏覽器查看這段代碼段的 html 源代碼鲤氢,可以發(fā)現 Pygments 的工作原理是把代碼切分成一個個單詞,然后為這些單詞添加 css 樣式西潘,不同的詞應用不同的樣式卷玉,這樣就實現了代碼顏色的區(qū)分,即高亮了語法喷市。為此相种,還差最后一步,引入一個樣式文件來給這些被添加了樣式的單詞定義顏色品姓。我比較喜歡 friendly 樣式寝并,當然你也可以選擇自己喜歡的 css 文件下載并引入。

在 blog/css 目錄下新建一個 friendly.css 文件腹备,把[這個里面的內容](https://github.com/zmrenwu/django-blog-tutorial/blob/Step9_markdown-and-code-highlight-supported/blog/static/blog/css/friendly.css)復制進去衬潦,保存文件,然后在 base.html 中把樣式文件文件引入馏谨,記得使用前面介紹過的 {% static %} 模板標簽來引入靜態(tài)文件:

```html
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/friendly.css' %}">

好了别渔,看看效果,大功告成惧互,終于可以愉快地貼代碼了哎媚。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喊儡,隨后出現的幾起案子拨与,更是在濱河造成了極大的恐慌,老刑警劉巖艾猜,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件买喧,死亡現場離奇詭異,居然都是意外死亡匆赃,警方通過查閱死者的電腦和手機淤毛,發(fā)現死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來算柳,“玉大人低淡,你說我怎么就攤上這事。” “怎么了蔗蹋?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵何荚,是天一觀的道長。 經常有香客問我猪杭,道長餐塘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任皂吮,我火速辦了婚禮戒傻,結果婚禮上,老公的妹妹穿的比我還像新娘蜂筹。我一直安慰自己稠鼻,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布狂票。 她就那樣靜靜地躺著,像睡著了一般熙暴。 火紅的嫁衣襯著肌膚如雪闺属。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天周霉,我揣著相機與錄音掂器,去河邊找鬼。 笑死俱箱,一個胖子當著我的面吹牛国瓮,可吹牛的內容都是我干的。 我是一名探鬼主播狞谱,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼乃摹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了跟衅?” 一聲冷哼從身側響起孵睬,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伶跷,沒想到半個月后掰读,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡叭莫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年蹈集,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片雇初。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡拢肆,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情善榛,我是刑警寧澤辩蛋,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站移盆,受9級特大地震影響悼院,放射性物質發(fā)生泄漏。R本人自食惡果不足惜咒循,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一据途、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧叙甸,春花似錦颖医、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至僚祷,卻和暖如春佛致,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辙谜。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工俺榆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人装哆。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓罐脊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蜕琴。 傳聞我的和親對象是個殘疾皇子萍桌,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內容