Django 博客开发教程 9 - 支持 Markdown 语法和代码高亮

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

安装 Python Markdown

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

在 detail 视图中渲染 Markdown

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

blog/views.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)
    # 记得在顶部引入 markdown 模块
    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 小时。以下是我学习中的一些参考资料:

# 一级标题

## 二级标题

### 三级标题

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

> 这是一段引用

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

如果你发现无法显示代码块,即代码无法换行,请检查代码块的语法是否书写有误。代码块的语法如上边的测试文本中最后一段所示。

你可能想在文章中插入图片,目前能做的且推荐做的是使用外链引入图片。比如将图片上传到七牛云这样的云存储服务器,然后通过 Markdown 的图片语法将图片引入。Markdown 引入图片的语法为:

safe 标签

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

safe 是 Django 模板系统中的过滤器(Filter),可以简单地把它看成是一种函数,其作用是作用于模板变量,将模板变量的值变为经过滤器处理过后的值。例如这里 {{ post.body|safe }},本来 {{ post.body }} 经模板系统渲染后应该显示 body 本身的值,但是在后面加上 safe 过滤器后,渲染的值不再是body 本身的值,而是由 safe 函数处理后返回的值。过滤器的用法是在模板变量后加一个 | 管道符号,再加上过滤器的名称。可以连续使用多个过滤器,例如 {{ var|filter1|filter2 }}。

代码高亮

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

安装 Pygments

首先我们需要安装 Pygments,激活虚拟环境,运行: pip install Pygments 安装即可。

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

引入样式文件

在项目的 blog\static\blog\css\highlights\ 目录下应该能看到很多 .css 样式文件,这些文件是用来提供代码高亮样式的。选择一个你喜欢的样式文件,在 base.html 引入即可(别忘了使用 static 模板标签)。比如我比较喜欢 github.css 的样式,那么引入这个文件:

templates/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/highlights/github.css' %}">

这里 + 号表示添加这行代码。好了,看看效果,大功告成,终于可以愉快地贴代码了。

注意:如果你按照教程中的方法做完后发现代码依然没有高亮,请依次检查以下步骤:

  1. 确保在渲染文本时添加了 markdown.extensions.codehilite 拓展,详情见上文。
  2. 确保安装了 Pygments。
  3. 确保代码块的 Markdown 语法正确,**特别是指明该代码块的语言类型**,具体请参见上文中 Markdown 的语法示例。
  4. 在浏览器端代码块的源代码,看代码是否被 pre 标签包裹,并且代码的每一个单词都被 span 标签包裹,且有一个 class 属性值。如果没有,极有可能是前三步中某个地方出了问题。
  5. 确保用于代码高亮的样式文件被正确地引入,具体请参见上文中引入样式文件的讲解。
  6. 有些样式文件可能对代码高亮没有作用,首先尝试用 github.css 样式文件做测试。

总结

本章节的代码位于:Step9: markdown and code highlight supported

如果遇到问题,请通过下面的方式寻求帮助。

更多Django 教程,请访问 追梦人物的博客

时间: 2024-12-28 12:17:59

Django 博客开发教程 9 - 支持 Markdown 语法和代码高亮的相关文章

Django 博客开发教程 15 - 使用 Fabric 自动化部署

在 使用 Nginx 和 Gunicorn 部署 Django 博客 中,我们通过手工方式将代码部署到了服务器.整个过程涉及到十几条命令,输了 N 个字符.一旦我们本地的代码有更新,整个过程又得重复来一遍,这将变得非常繁琐. 使用 Fabric 可以在服务器中自动执行命令.因为整个代码部署过程都是相同的,只要我们用 Fabric 写好部署脚本,以后就可以通过运行脚本自动完成部署了. 安装 Fabric Fabric 目前仅支持 Python2,如果你的系统中只有 Python3 版本,请先安装一

Django 博客开发教程 1 - 搭建开发环境

本教程使用的开发环境 本教程写作时开发环境的系统平台为 Windows 10 (64 位),Python 版本为 3.5.2 (64 位),Django 版本为 1.10.6. 建议尽可能地与教程的开发环境保持一致(尤其是 Python 与 Django 版本),避免不必要的麻烦.推荐的 Python 版本为 Python 3.4 或以上,Django 版本号必须为 Django 1.10.x. 注意:本教程将尽量保证兼容 Python 2,但不会在 Python 2 环境下做测试.如果你因为某

Django 博客开发教程 13 - 已知小问题修正

在模型中指定排序 为了让文章(Post)按发布时间逆序排列,即最新发表的文章排在文章列表的最前面,我们对返回的文章列表进行了排序,即各个视图函数中都有类似于 Post.objects.all().order_by('-created_time') 这样的代码,这导致了很多重复.因为只要是返回的文章列表,基本都是逆序排列的,因此我们可以在 Post 模型中指定 Post 的自然排序方式. Django 允许我们在 models.Model 的子类里定义一个 Meta 的内部类,这个内部类通过指定一

Django 博客开发教程 7 - 在 Django Admin 后台发布文章

在此之前我们完成了 Django 博客首页视图的编写,我们希望首页展示发布的博客文章列表,但是它却抱怨:暂时还没有发布的文章!如它所言,我们确实还没有发布任何文章,本节我们将使用 Django 自带的 Admin 后台来发布我们的博客文章. 创建 Admin 后台管理员账户 要想进入Django Admin 后台,首先需要创建一个超级管理员账户.我们在 让 Django 完成翻译:迁移数据库 中已经创建了一个后台账户,但如果你没有按照前面的步骤创建账户的话,可以运行 python manage.

Django 博客开发教程 6 - 真正的 Django 博客首页视图

在此之前我们已经编写了 Blog 的首页视图,并且配置了 URL 和模板,让 Django 能够正确地处理 HTTP 请求并返回合适的 HTTP 响应.不过我们仅仅在首页返回了一句话:欢迎访问我的博客.这是个 Hello World 级别的视图函数,我们需要编写真正的首页视图函数,当用户访问我们的博客首页时,他将看到我们发表的博客文章列表,就像 演示项目 里展示的这样. 首页视图函数 上一节我们阐明了 Django 的开发流程.即首先配置 URL,把 URL 和相应的视图函数绑定,一般写在 ur

Django 博客开发教程 5 - Django 博客首页视图

Django 处理 HTTP 请求 Web 应用的交互过程其实就是 HTTP 请求与响应的过程.无论是在 PC 端还是移动端,我们通常使用浏览器来上网,上网流程大致来说是这样的: 我们打开浏览器,在地址栏输入想访问的网址,比如 http://zmrenwu.com/(当然你也可能从收藏夹里直接打开网站,但本质上都是一样的). 浏览器知道我们想要访问哪个网址后,它在后台帮我们做了很多事情.主要就是把我们的访问意图包装成一个 HTTP 请求,发给我们想要访问的网址所对应的服务器.通俗点说就是浏览器帮

Django 博客开发教程 0 - 前言

Django 是使用 Python 编写的一个开源 Web 框架,可以用它来快速搭建一个高性能的网站. Django makes it easier to build better Web apps more quickly and with less code. Django 让你以更快的速度.更少的代码.更轻松的方式搭建更好的 Web 应用. 本教程将带你使用 Django 快速开发属于自己的博客网站. 教程特点 免费.中文.零基础,完整的项目,基于最新版 Django 1.10 和 Pyt

Django 博客开发教程 3 - 创建 Django 博客的数据库模型

设计博客的数据库表结构 博客最主要的功能就是展示我们写的文章,它需要从某个地方获取博客文章数据才能把文章展示出来,通常来说这个地方就是数据库.我们把写好的文章永久地保存在数据库里,当用户访问我们的博客时,Django 就去数据库里把这些数据取出来展现给用户. 博客的文章应该含有标题.正文.作者.发表时间等数据.一个更加现代化的博客文章还希望它有分类.标签.评论等.为了更好地存储这些数据,我们需要合理地组织数据库的表结构. 我们的博客初级版本主要包含博客文章,文章会有分类以及标签.一篇文章只能有一

Django 博客开发教程 2 - 建立 Django 博客应用

建立博客应用 我们已经建立了 Django 博客的项目工程,并且成功地运行了它.不过到目前为止这一切都还只是 Django 为我们创建的项目初始内容,Django 不可能为我们初始化生成博客代码,这些功能性代码都得由我们自己编写. Django 鼓励我们把自己编写的代码组织到应用(Application)里,并且最好是一个应用只提供一种功能.例如我们要开发的 Django 博客,相关的代码都放在 blog 这个应用里.其实应用也没什么复杂的,不过是把功能相关的代码组织到一个文件夹里,这个文件夹就