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

<link rel="stylesheet" href="{% static 'blog/css/pace.css' %}">
<link rel="stylesheet" href="{% static 'blog/css/custom.css' %}">

+ <link rel="stylesheet" href="{% static 'blog/css/friendly.css' %}">

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容