HelloDjango 第 09 篇:讓博客支持 Markdown 語法和代碼高亮

<p align="center">做者:HelloGitHub-<strong>追夢人物</strong></p>css

文中涉及的示例代碼,已同步更新到 HelloGitHub-Team 倉庫html

爲了讓博客文章具備良好的排版,顯示更加豐富的格式,咱們使用 Markdown 語法來書寫博文。Markdown 是一種 HTML 文本標記語言,只要遵循它約定的語法格式,Markdown 的解析工具就可以把 Markdown 文檔轉換爲標準的 HTML 文檔,從而使文章呈現更加豐富的格式,例如標題、列表、代碼塊等等 HTML 元素。因爲 Markdown 語法簡單直觀,不用超過 5 分鐘就能夠輕鬆掌握經常使用的標記語法,所以你們青睞使用 Markdown 書寫 HTML 文檔。下面讓咱們的博客也支持使用 Markdown 寫做。python

安裝 Python Markdown

將 Markdown 格式的文本解析成標準的 HTML 文檔是一個複雜的工程,好在已有好心人幫咱們完成了這些工做,直接拿來使用便可。首先安裝 Markdown,這是一個 Python 第三方庫,在項目根目錄下運行命令 pipenv install markdowngit

在 detail 視圖中解析 Markdown

將 Markdown 格式的文本解析成 HTML 文本很是簡單,只需調用這個庫的 markdown 方法。咱們書寫的博客文章內容存在 Postbody 屬性裏,回到咱們的詳情頁視圖函數,對 postbody 的值作一下解析,把 Markdown 文本轉爲 HTML 文本再傳遞給模板:程序員

blog/views.py

import markdown
from django.shortcuts import get_object_or_404, render

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 則容許自動生成目錄(在之後會介紹)。github

來測試一下效果,進入後臺,此次咱們發佈一篇用 Markdown 語法寫的測試文章看看,你可使用如下的 Markdown 測試代碼進行測試,也能夠本身書寫你喜歡的 Markdown 文本。假設你是 Markdown 新手請參考一下這些教程,必定學一下,保證你能夠在 5 分鐘內掌握經常使用的語法格式,而之後對你寫做受用無窮。可謂充電 5 分鐘,通話 2 小時。如下是我學習中的一些參考資料:web

# 一級標題

## 二級標題

### 三級標題

- 列表項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})
​```

若是你發現沒法顯示代碼塊,即代碼沒法換行,請檢查代碼塊的語法是否書寫有誤。代碼塊的語法如上邊的測試文本中最後一段所示。django

你可能想在文章中插入圖片,目前能作的且推薦作的是使用外鏈引入圖片。好比將圖片上傳到七牛雲這樣的雲存儲服務器,而後經過 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 的語法使咱們容易地書寫代碼塊,可是目前來講,顯示的代碼塊裏的代碼沒有任何顏色,很不美觀,也難以閱讀,要是可以像代碼編輯器裏同樣讓代碼高亮就行了。

代碼高亮咱們藉助 js 插件來實現,其原理就是 js 解析整個 html 頁面,而後找到代碼塊元素,爲代碼塊中的元素添加樣式。咱們使用的插件叫作 highlight.js 和 highlightjs-line-numbers.js,前者提供基礎的代碼高亮,後者爲代碼塊添加行號。

首先在 base.html 的 head 標籤裏引入代碼高亮的樣式,有多種樣式供你選擇,這裏咱們選擇 GitHub 主題的樣式。樣式文件直接經過 CDN 引入,同時在 style 標籤裏自定義了一點元素樣式,使得代碼塊的顯示效果更加完美。

<head>
  ...
  <link href="https://cdn.bootcss.com/highlight.js/9.15.8/styles/github.min.css" rel="stylesheet">

  <style>
    .codehilite {
      padding: 0;
    }

    /* for block of numbers */
    .hljs-ln-numbers {
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      -khtml-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;

      text-align: center;
      color: #ccc;
      border-right: 1px solid #CCC;
      vertical-align: top;
      padding-right: 5px;
    }

    .hljs-ln-n {
      width: 30px;
    }

    /* for block of code */
    .hljs-ln .hljs-ln-code {
      padding-left: 10px;
      white-space: pre;
    }
  </style>
</head>

而後是引入 js 文件,由於應該等整個頁面加載完,插件再去解析代碼塊,因此把 js 文件的引入放在 body 底部:

<body>
  <script src="https://cdn.bootcss.com/highlight.js/9.15.8/highlight.min.js"></script>
  <script src="https://cdn.bootcss.com/highlightjs-line-numbers.js/2.7.0/highlightjs-line-numbers.min.js"></script>
  <script>
    hljs.initHighlightingOnLoad();
    hljs.initLineNumbersOnLoad();
  </script>
</body>

很是簡單,經過 CDN 引入 highlight.js 和 highlightjs-line-numbers.js,而後初始化了兩個插件。再來看下效果,很是完美!

<p align="center">歡迎關注 HelloGitHub 公衆號,獲取更多開源項目的資料和內容</p>

原文出處:https://www.cnblogs.com/xueweihan/p/11387769.html

相關文章
相關標籤/搜索