閱讀418 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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 方法即可。我們書寫的博客文章內容存在 Postbody 屬性裏,回到我們的詳情頁視圖函數,對 postbody 的值做一下渲染,把 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 測試

代碼高亮

程序員寫博客免不了要插入一些代碼,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' %}">

這裏 + 號表示添加這行代碼。好了,看看效果,大功告成,終於可以愉快地貼代碼了。

代碼高亮

注意:如果你按照教程中的方法做完後發現代碼依然沒有高亮,請依次檢查以下步驟:

  1. 確保在渲染文本時添加了 markdown.extensions.codehilite 拓展,詳情見上文。
  2. 確保安裝了 Pygments。
  3. 確保代碼塊的 Markdown 語法正確,**特別是指明該代碼塊的語言類型**,具體請參見上文中 Markdown 的語法示例。
  4. 在瀏覽器端代碼塊的源代碼,看代碼是否被 pre 標簽包裹,並且代碼的每一個單詞都被 span 標簽包裹,且有一個 class 屬性值。如果沒有,極有可能是前三步中某個地方出了問題。
  5. 確保用於代碼高亮的樣式文件被正確地引入,具體請參見上文中引入樣式文件的講解。
  6. 有些樣式文件可能對代碼高亮沒有作用,首先嚐試用 github.css 樣式文件做測試。

總結

本章節的代碼位於:Step9: markdown and code highlight supported

如果遇到問題,請通過下麵的方式尋求幫助。

更多Django 教程,請訪問 追夢人物的博客

最後更新:2017-05-31 12:02:41

  上一篇:go  《Spring Data實戰》——2.2 定義查詢方法
  下一篇:go  Django 博客開發教程 8 - 博客文章詳情頁