Django 開發部落格使用 Markdown 來為文章提供排版支援。Markdown 在渲染內容的同時還可以自動提取整個內容的目錄結構,本文將教你如何使用 Markdown 來為文章自動生成目錄。
博文模型
例如建立的博文模型如下:
class Post(models.Model):
# Other fields ...
body = models.TextField()
檢視函式
在博文詳情檢視函式中使用Markdown擴充套件為 post 新增目錄屬性,如下:
import markdown
from django.shortcuts import render, get_object_or_404
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', {'post': post})
HTML中渲染目錄
<div>
{{ post.toc|safe }}
</div>
美化標題錨點
文章內容的標題被設定了錨點,點選目錄中的某個標題,頁面就會跳到該文章內容中標題所在的位置,這時候瀏覽器的 URL 顯示的值可能不太美觀,比如像下面的樣子:
#_1
就是錨點,Markdown 在設定錨點時利用的是標題的值,由於通常我們的標題都是中文,Markdown 沒法處理,所以它就忽略的標題的值,而是簡單地在後面加了個 _1 這樣的錨點值。
為了解決這一個問題,我們需要修改一下傳給 extentions 的引數,其具體做法如下:
import markdown
from django.shortcuts import render, get_object_or_404
from django.utils.text import slugify
from markdown.extensions.toc import TocExtension
def detail(request, pk):
post = get_object_or_404(Post, pk=pk)
md = markdown.Markdown(extensions=[
'markdown.extensions.extra',
'markdown.extensions.codehilite',
TocExtension(slugify=slugify),
])
post.body = md.convert(post.body)
return render(request, 'blog/detail.html', {'post': post, 'toc': md.toc})
和上一節不同的是,extensions
中的 toc
擴充不再是字串 markdown.extensions.toc
,而是 TocExtension
的例項。TocExtension 在例項化時其 slugify 引數可以接受一個函式作為引數,這個函式將被用於處理標題的錨點值。Markdown 內建的處理方法不能處理中文標題,所以我們使用了 django.utils.text 中的 slugify 方法,該方法可以很好地處理中文。
這時候標題的錨點 URL 變得好看多了。
本作品採用《CC 協議》,轉載必須註明作者和本文連結