Django搭建个人博客:渲染Markdown文章目录

3463阅读 · 28评论 · 2019/01/01发布   前往评论

对会读书的人来说,读一本书要做的第一件事,就是仔细阅读这本书的目录。阅读目录可以对整体内容有所了解,并清楚地知道感兴趣的部分在哪里,提高阅读质量。

博文也是同样的,好的目录对博主和读者都很有帮助。更进一步的是,还可以在目录中设置锚点,点击标题就立即前往该处,非常的方便。

文中的目录

之前我们已经为博文支持了Markdown语法,现在继续增强其功能。

有折腾代码高亮的痛苦经历之后,设置Markdown的目录扩展就显得特别轻松了。

修改文章详情视图:

article/views.py

...

# 文章详情
def article_detail(request, id):
    ...
    article.body = markdown.markdown(article.body,
        extensions=[
        'markdown.extensions.extra',
        'markdown.extensions.codehilite',

        # 目录扩展
        'markdown.extensions.TOC',
        ]
    )
    ...

仅仅是将markdown.extensions.TOC扩展添加了进去。

注意:有读者反映某些版本下 markdown.extensions.TOC 会报错。如果遇到这种情况,请尝试修改为 markdown.extensions.toc

代码增加这一行就足够了。为了方便测试,往之前的文章中添加几个一级标题、二级标题等。

还记得Markdown语法如何写标题吗?一级标题:# title1,二级标题:## title2

然后你可以在文中的任何地方插入[TOC]字符串,目录就自动生成好了:

点击标题,页面就立即前往相应的标题处(即“锚点”的概念)。

任意位置的目录

上面的方法只能将目录插入到文章当中。如果我想把目录插入到页面的任何一个位置呢?

也简单,这次需要修改Markdown的渲染方法:

article/views.py

...

def article_detail(request, id):
    ...

    # 修改 Markdown 语法渲染
    md = markdown.Markdown(
        extensions=[
        'markdown.extensions.extra',
        'markdown.extensions.codehilite',
        'markdown.extensions.toc',
        ]
    )
    article.body = md.convert(article.body)

    # 新增了md.toc对象
    context = { 'article': article, 'toc': md.toc }

    return render(request, 'article/detail.html', context)

为了能将toc单独提取出来,我们先将Markdown类赋值给一个临时变量md,然后用convert()方法将正文渲染为html页面。通过md.toc将目录传递给模板。

注意markdown.markdown()markdown.Markdown()的区别

更详细的解释见:官方文档

为了将新的目录渲染到页面中,需要修改文章详情模板:

templates/article/detail.html

...

<div class="container">
    <div class="row">
        <!-- 将原有内容嵌套进新的div中 -->
        <div class="col-9">
            <h1 class="mt-4 mb-4">{{ article.title }}</h1>
            <div class="alert alert-success">
                ...
            </div>
        </div>

        <!-- 新增的目录 -->
        <div class="col-3 mt-4">
            <h4><strong>目录</strong></h4>
            <hr>
            <div>
                {{ toc|safe }}
            </div>
        </div>
    </div>
</div>

...
  • 重新布局,将原有内容装进col-9的容器中,将右侧col-3的空间留给目录
  • toc需要|safe标签才能正确渲染

重新打开页面:

总结

完成了文章的目录功能,至此文章详情页面也比较完善了。

转载请注明出处。




本文作者: 杜赛
发布时间: 2019年01月01日 - 15:06
最后更新: 2019年10月31日 - 20:21
知识共享许可协议   转载请保留原文链接及作者


登录 后回复

共有28条评论

avatar
只能这样啦 么么哒! 3

在手机端能上传图片?

10个月前 回复


avatar
杜赛 [博主] 只能这样啦 么么哒! 3

手机上传图片?啥意思

10个月前 回复


avatar
只能这样啦 杜赛 [博主] 么么哒! 3

用手机发博文,博文中包含图片

10个月前 回复


avatar
杜赛 [博主] 只能这样啦 么么哒! 3

Markdown中的图片实际上只是一个url而已,用手机写一样的。

上传图片的话需要另外写代码,我准备后面讲的

10个月前 回复


avatar
只能这样啦 杜赛 [博主] 么么哒! 3

ok .我慢慢等。

10个月前 回复


avatar
17647361832 么么哒! 4

请问如果想让代码显示每一行的行数应该怎么写呢,网上没有找到相关的说明

9个月前 回复


avatar
杜赛 [博主] 17647361832 么么哒! 3

python-markdown默认是不显示行号的。

想显示行号需要向高亮扩展中传入参数:

# Moarkdown 语法渲染
md = markdown.Markdown(
    extensions=[
    ...

    # 语法高亮扩展
    'markdown.extensions.codehilite(linenums=True)',

    ...
)

默认的样式是白色主题;并且由于代码块会被包裹到table中去,有可能样式看起来不太好看(特别是深色主题)。

想修改样式也可以,直接在css中改就行了。因为代码高亮本质上就是css样式的应用。

9个月前 回复


avatar
流天 杜赛 [博主] 么么哒! 3

我这边加入linenums=True出现语法错误。看源码

试试其他也用。网上其他地方都没有说明,也试了元祖或者列表的方式还是不行。

不知该咋办?

7个月前 回复


avatar
杜赛 [博主] 流天 么么哒! 3

你用的是Markdown类吧?

注意是markdown.Markdown,不是markdown.markdown

或者把库换成教程相同的版本,写个小脚本测试一下。

7个月前 回复


avatar
流天 杜赛 [博主] 么么哒! 3

7个月前 回复


avatar
wangfanazz 么么哒! 4

我想问一下这个文章目录怎么才能一直在右边显示,而不是随着文章的滚动目录也就上去了?

7个月前 回复


avatar
杜赛 [博主] wangfanazz 么么哒! 3

GitHub上有一个开源js插件,叫sticky sidebar,您找找看

7个月前 回复


avatar
stormsha 么么哒! 3

看到博主的炫酷评论区,也给自己的站点加了炫酷的特效

https://stormsha.com

7个月前 回复


avatar
杜赛 [博主] stormsha 么么哒! 4

刚去参观了贵站,很漂亮,功能也齐全,自愧不如yes

友链来一发?

7个月前 回复


avatar
pidada 么么哒! 3

博主,课程很详细,很适合初学者!yes

请教一个前端的问题:我按照你的教程来,为什么总是出来的前端界面的效果和你的不同呢?

比如:在这个章中,我的目录是显示在下面的

5个月前 回复


avatar
杜赛 [博主] pidada 么么哒! 3

说明你的模板写得和我不一样。仔细检查

5个月前 回复


avatar
pidada 杜赛 [博主] 么么哒! 3

博主,你这章中的前端代码的那些换行是特意的吗

5个月前 回复


avatar
杜赛 [博主] pidada 么么哒! 3

什么意思?

5个月前 回复


avatar
ac1864 么么哒! 4

过关,
markdown还是比较简单的。

5个月前 回复


avatar
sys0613 么么哒! 3

请问教程左侧这个目录列表,也是用markdown实现的么?还是用什么插件实现的?

4个月前 回复


avatar
杜赛 [博主] sys0613 么么哒! 3

也是Markdown实现了,外加了一个智能侧边栏的脚本。教程后面章节有讲的。

4个月前 回复


avatar
sys0613 么么哒! 6

我是python3.6版本,今天发现

 

'markdown.extensions.TOC',

无效,必须得

'markdown.extensions.toc',

小写的toc,才可以,否则就报找不到模块。也不知道原因了。发出来供别人参考吧。

3个月前 回复


avatar
楚糖的糖 sys0613 么么哒! 3

厉害厉害,我就是这个问题困扰了好久

2个月前 回复


avatar
sys0613 楚糖的糖 么么哒! 3

共同学习,我也是在摸着石头过河,新手一枚,哈哈

2个月前 回复


avatar
seekdoor 楚糖的糖 么么哒! 2

啊哈,我也是遇到这个问题

2个月前 回复


avatar
fcmxmk sys0613 么么哒! 1

3.6 toc可以, 谢谢告知

16天前 回复


avatar
fcmxmk 么么哒! 1

老师, 目录老是会飘要怎么处理, 假设有几十个一级目录(没有满一页), 按教程不做调整, 就算只有几个一级目录, 在滚动页面的时候, 目录就会往左边飘.

我现在设置的两种方式好像都不治本,

一种是删除目录那里的 col-3, 这种虽然不会左右飘, 但是在滚动到底部的时候, 还是会跳一下;

一种是 topSpacing 和 bottomSpacing 两个值设置大一点, 比如都设置为 60, 但滚动到底部时, 目录还是会往右边飘一点;

10天前 回复


avatar
杜赛 [博主] fcmxmk 么么哒! 1

不太清楚你的具体情况。

如果你用的是 sticky-sidebar 这个插件,那就去看看它的文档里有没有解决办法。

也有可能插件本身就有些缺陷,那就不太好解决,只有找找其他替代插件,或者想折中的方法。

10天前 回复