10. 支持 markdown 语法和代码高亮

本教程内容已过时,更新版教程请访问: Django 博客开发入门教程

这是 Django 博客教程的第 10 篇,在阅读此篇教程以前,请确保你已阅读 Django 博客教程的前 9 篇:
1. Django 博客教程:前言
2. 搭建开发环境
3. 建立我们的 django 博客应用
4. 创建 django 博客的数据库模型
5. 让 django 完成翻译——迁移数据库模型
6. django 博客首页视图
7. 真正的 django 博客首页视图
8. 在 django admin 后台发布我们的文章
9. 博客文章详情页

为了让博客文章具有良好的排版,显示更加丰富的格式,我们使用 markdown 语法来书写我们的博文。markdown 是一种 html 文本标记语言,只要遵循它约定的语法格式,markdown 的渲染器就能够把我们写的文章转换为标准的 html 文档,从而让我们的文章呈现更加丰富的格式,例如标题、列表、代码块等等 html 元素。由于 markdown 语法简单直观,不用超过 5 分钟就可以掌握常用的标记语法,这就是大家青睐使用 markdown 书写 html 文档的原因。下面让我们的博客也支持使用 markdown 书写。

将 markdown 格式的文本渲染成标准的 html 文档是一个复杂的工作,好在已有好心人写好了,我们直接使用即可。首先安装 markdown,这是一个 Python 第三方库,进入虚拟环境,然后 pip install markdown 安装即可。

将 markdown 格式的文本渲染成 html 文本非常简单,只需调用这个库的 markdown 方法即可。我们书写的内容存在 Post 的 body 属性里,回到我们的详情页视图函数,对获取的 post 的 body 的值做一下渲染,把 markdown 文本转为 html 文本再传递给模板:

blog/details.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)
    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 小时。以下是我学习中的一些参考资料:

Markdown——入门指南

Markdown 语法说明 (简体中文版)

# 一级标题

## 二级标题

### 三级标题

- 列表项1
- 列表项2
- 列表项3

> 这是一段引用

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

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

## html safe 标签的使用。

我们在发布的文章详情页没有看到预期的效果,而是类似于一堆乱码一样的 html 标签,这些标签本应该在浏览器显示它本身的格式,但是 django 出于安全方面的考虑,任何的 html 代码在 django 的模板中都会被转义(即输入原始的 html 文档代码,而不是经浏览器渲染后的格式),为了解除转义,只需在模板标签使用 safe 过滤器即可,告诉 django,这段文本是安全的,你什么也不用做。在模板中找到展示博客文章主体的 {{ post.body }} 部分,为其加上 safe 过滤器,{{ post.body|safe }},大功告成,这下看到预期效果了。

![](http://upload-images.jianshu.io/upload_images/1008138-ec21a310f98cb005.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 代码高亮

程序员写博客免不了要插入一些代码,markdown 的语法使我们容易地书写代码块,但是目前来说,显示的代码块里的代码没有任何颜色,很不美观,也难以阅读,要是能够像我们的编辑器里一样让代码高亮就好了。虽然我们在渲染时使用了 codehilite 拓展,但这只是实现代码高亮的第一步,还需要简单的几步才能达到我们的最终目的。

首先我们需要安装 Pygments,进入虚拟环境,运行: `pip install Pygments`

搞定了,虽然我们除了安装了一下 Pygments 什么也没做,但 Markdown 使用 Pygments 在后台为我们做了很多事。如果你打开博客详情页,找到一段代码段,在浏览器查看这段代码段的 html 源代码,可以发现 Pygments 的工作原理是把代码切分成一个个单词,然后为这些单词添加 css 样式,不同的词应用不同的样式,这样就实现了代码颜色的区分,即高亮了语法。为此,还差最后一步,引入一个样式文件来给这些被添加了样式的单词定义颜色。我比较喜欢 friendly 样式,当然你也可以选择自己喜欢的 css 文件下载并引入。

在 blog/css 目录下新建一个 friendly.css 文件,把[这个里面的内容](https://github.com/zmrenwu/django-blog-tutorial/blob/Step9_markdown-and-code-highlight-supported/blog/static/blog/css/friendly.css)复制进去,保存文件,然后在 base.html 中把样式文件文件引入,记得使用前面介绍过的 {% static %} 模板标签来引入静态文件:

```html
base.html




+ 

好了,看看效果,大功告成,终于可以愉快地贴代码了。

你可能感兴趣的:(10. 支持 markdown 语法和代码高亮)