Django 使用Markdown书写文章详解

上一章我们实现了文章详情页面。为了让文章正文能够进行标题、加粗、引用、代码块等不同的排版(像在Office中那样!),我们将使用Markdown语法。

安装Markdown

Markdown是一种轻量级的标记语言,它允许人们“使用易读易写的纯文本格式编写文档,然后转换成有效的或者HTML文档。建议读者一定要花五分钟时间熟悉一下Markdown的语法,熟练后码字效率一定会大幅提高。

关于Markdown语法看这里:Markdown 语法介绍

安装markdown也很简单:进入虚拟环境,输入指令pip install markdown即可。

使用Markdown

为了将Markdown语法书写的文章渲染为HTML文本,首先改写article/views.pyarticle_detail()

article/views.py

...

# 引入markdown模块
import markdown

def article_detail(request, id):
    article = ArticlePost.objects.get(id=id)

    # 将markdown语法渲染成html样式
    article.body = markdown.markdown(article.body,
        extensions=[
        # 包含 缩写、表格等常用扩展
        'markdown.extensions.extra',
        # 语法高亮扩展
        'markdown.extensions.codehilite',
        ])

    context = { 'article': article }
    return render(request, 'article/detail.html', context)

代码中markdown.markdown语法接收两个参数:第一个参数是需要渲染的文章正文article.body;第二个参数载入了常用的语法扩展,markdown.extensions.extra中包括了缩写、表格等扩展,markdown.extensions.codehilite则是后面要使用的代码高亮扩展。

然后,修改templates/article/detail.html中有关文章正文的部分:

templates/article/detail.html

...

# 在 article.body 后加上 |safe 过滤器
<p>{{ article.body|safe }}</p>

Django出于安全的考虑,会将输出的HTML代码进行转义,这使得article.body中渲染的HTML文本无法正常显示。管道符|是Django中过滤器的写法,而|safe就类似给article.body贴了一个标签,表示这一段字符不需要进行转义了。

这样就把Markdown语法配置好了。

启动服务器,在后台中新录入一条用markdown语法书写的文章,内容如下:

# 国风·周南·关雎
---
**关关雎鸠,在河之洲。窈窕淑女,君子好逑。**

参差荇菜,左右流之。窈窕淑女,寤寐求之。

---
+ 列表一
+ 列表二
    + 列表二-1
    + 列表二-2
---

​```python
def article_detail(request, id):
    article = ArticlePost.objects.get(id=id)
    # 将markdown语法渲染成html样式
    article.body = markdown.markdown(article.body,
        extensions=[
        # 包含 缩写、表格等常用扩展
        'markdown.extensions.extra',
        # 语法高亮扩展
        'markdown.extensions.codehilite',
        ])
    context = { 'article': article }
    return render(request, 'article/detail.html', context)
​```

注意:直接复制本段Markdown文字到你的项目中,可能导致语法高亮不正常(猜测是换行符导致的?)。建议读者手动输入。感谢读者micronuths的反馈

返回文章详情,结果如下:

很好,但是代码块还是不怎么好看。

写技术文章没有代码高亮怎么行。继续努力。

代码高亮

static目录中新建一个目录md_css/,一会儿放置代码高亮的样式文件。

重新打开一个命令行窗口,进入虚拟环境,安装Pygments:pip install Pygments

Pygments是一种通用语法高亮显示器,可以帮助我们自动生成美化代码块的样式文件。

在命令行中进入刚才新建的md_css目录中,输入Pygments指令:

pygmentize -S monokai -f html -a .codehilite > monokai.css

这里有一点需要注意, 生成命令中的 -a 参数需要与真实页面中的 CSS Selector 相对应,即.codehilite这个字段在有些版本中应写为.highlight。如果后面的代码高亮无效,很可能是这里出了问题。

回车后检查一下,在md_css目录中是否自动生成了一个叫monokai.css的文件,这是一个深色背景的高亮样式文件。

接下来我们在base.html中引用这个文件:

templates/base.html

<head>
    ...
    <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">

    <!-- 引入monikai.css -->
    <link rel="stylesheet" href="{% static 'md_css/monokai.css' %}">

</head>
...

重新启动服务器,顺利的话看到如下:

除了Monokai这个深色的样式外,Pygments还内置了很多其他的样式,这个就看喜好选择了。

各种不同样式可以在这里参照:pygments-css


故障排查

此节 2018/12/22 新增

代码高亮这里遇到问题的读者比较多,因此展开讲一下如何排查问题。其他地方遇到类似问题也可以这样去做。

首先请查看网页的源代码:用Chrome浏览器的同学按Ctrl+U,其他浏览器请自行查找快捷键。

找到正文中书写代码块的部分。正常情况下这部分的源代码应该是这样的:

根据源代码,可能出现的问题分为以下两种:

  • 如果看到的源代码跟上面的很像,很可能是模板出了问题

  • 如果看到的源代码跟上面的区别很大,很可能是视图出了问题

下面分别说说怎么解决。

如果模板出了问题:

  • 检查monokai.css这个文件是否正常载入。检查方法就是直接点击网页源代码中的<link>引用链接,看是否正常。

    • 如果链接正常,看一下每行开头字段是.codehilite还是highlight,确保和包裹代码块的字段相对应

    • 如果链接不正常,查看settings.py中是否忘记写STATIC_URL或者STATICFILES_DIRS字段

  • 进入浏览器开发者模式,查看monokai.css样式是否被别的样式所覆盖。Chrome请按F12或者Ctrl+Shift+I

  • 最后清除浏览器缓存,重启服务器

如果视图出了问题:

  • 重新安装 markdown 和 pygments,卸载指令是pip uninstall xxx

  • 注释掉markdown.extensions.extra或者markdown.extensions.codehilite,刷新网页源代码看看是否有变化。如果没有变化说明扩展没有正确载入

  • 最后清除浏览器缓存,重启服务器

特别提醒markdown中代码块的书写:

  • 开头:单独一行。三个点符(英文输入法时,Tab键上面那个键),后紧跟python这个单词

  • 正文:即代码本身。缩进请用4个空格

  • 结尾:单独一行。还是三个点符

遇到几个读者都是因为书写的问题,找了一个上午的Bug,痛不欲生...

如果以上步骤还没解决你的问题,不妨暂时跳过这一部分,不影响后面的学习。

自定义样式

此节 2019/6/1 新增

很多读者注意到博主的Markdown文章样式似乎比pygments生成的样式要漂亮一些。

确实是这样的。pygments提供的样式比较基础,满足不了各位大佬千奇百怪的需求,因此需要对文章样式进行深度定制。

定制的方法很多。首先你应该注意到了,pygments生成的其实就是普通的css文件而已,源码也不复杂,会一点点css基础就能看懂。你完全可以自由的改动源码,变换颜色、字间距、给代码块加圆角、增加图片阴影,都随便你。

另一个经常被读者问到的是,pygments的表格样式太难看了,自己从零定制表格样式又太麻烦,怎么办?博主的处理办法偷了个懒,在页面中用Jquery动态加载了Bootstrap的表格样式,就像这样:

<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>

<script>
    $('div#article_body table').addClass('table table-bordered');
    $('div#article_body thead').addClass('thead-light');
</script>

很方便就得到漂亮的表格。

注意这里只是示例,照搬代码可能会有错误。Jquery后面才会讲到,读者不懂的可先查阅一点基础知识。

总结

本章引进了Markdown语法以及代码高亮扩展,从此可以写排版漂亮的文章正文了。

下一章将学习如何创建一篇新的文章。

教程来源于Github,感谢杜赛 www.dusaiphoto.com大佬的无私奉献,致敬!

技术教程推荐

左耳听风 -〔陈皓〕

邱岳的产品实战 -〔邱岳〕

代码精进之路 -〔范学雷〕

MySQL 必知必会 -〔朱晓峰〕

Spark性能调优实战 -〔吴磊〕

React Hooks 核心原理与实战 -〔王沛〕

如何读懂一首诗 -〔王天博〕

PyTorch深度学习实战 -〔方远〕

结构学习力 -〔李忠秋〕