Django博客--5.让博客支持 Markdown 语法和代码高亮

文章目录

    • 0.前言
    • 1.安装 Python Markdown
    • 2.在 detail 视图中解析 Markdown
    • 3.safe 标签
    • 4.代码高亮
    • 5.效果展示

0.前言

Markdown 是一种 HTML 文本标记语言,只要遵循它约定的语法格式,Markdown 的解析工具就能够把 Markdown 文档转换为标准的 HTML 文档,从而使文章呈现更加丰富的格式,例如标题、列表、代码块等等 HTML 元素。

1.安装 Python Markdown

将 Markdown 格式的文本解析成标准的 HTML 文档是一个复杂的工程,好在已有好心人帮我们完成了这些工作,直接拿来使用即可。首先安装 Markdown,这是一个 Python 第三方库,在项目根目录下运行命令:
pipenv install markdown

2.在 detail 视图中解析 Markdown

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

文件位置:blog/views.py

import markdown
from django.shortcuts import get_object_or_404, render

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 语法说明:戳这里

3.safe 标签

如果此时运行服务器,在发布的文章详情页会出现类似于一堆乱码一样的 HTML 标签,这些标签本应该在浏览器显示它自身的格式,但是 django 出于安全方面的考虑,任何的 HTML 代码在 django 的模板中都会被转义(即显示原始的 HTML 代码,而不是经浏览器渲染后的格式)。

为了解除转义,只需在模板变量后使用 safe 过滤器即可,告诉 django,这段文本是安全的,你什么也不用做。在模板中找到展示博客文章内容的 { { post.body }} 部分,为其加上 safe 过滤器:{ { post.body|safe }}
Django博客--5.让博客支持 Markdown 语法和代码高亮_第1张图片

4.代码高亮

代码高亮我们借助 js 插件来实现,其原理就是 js 解析整个 html 页面,然后找到代码块元素,为代码块中的元素添加样式。我们使用的插件叫做 highlight.js 和 highlightjs-line-numbers.js,前者提供基础的代码高亮,后者为代码块添加行号。

首先在 base.html 的 head 标签里引入代码高亮的样式,有多种样式供你选择,这里我们选择 GitHub 主题的样式。样式文件直接通过 CDN 引入,同时在 style 标签里自定义了一点元素样式,使得代码块的显示效果更加完美。

<head>
  ...
  <link href="https://cdn.bootcss.com/highlight.js/9.15.8/styles/github.min.css" rel="stylesheet">

  <style>
    .codehilite {
     
      padding: 0;
    }

    /* for block of numbers */
    .hljs-ln-numbers {
     
      -webkit-touch-callout: none;
      -webkit-user-select: none;
      -khtml-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;

      text-align: center;
      color: #ccc;
      border-right: 1px solid #CCC;
      vertical-align: top;
      padding-right: 5px;
    }

    .hljs-ln-n {
     
      width: 30px;
    }

    /* for block of code */
    .hljs-ln .hljs-ln-code {
     
      padding-left: 10px;
      white-space: pre;
    }
  </style>
</head>

然后是引入 js 文件,因为应该等整个页面加载完,插件再去解析代码块,所以把 js 文件的引入放在 body 底部:

<body>
  <script src="https://cdn.bootcss.com/highlight.js/9.15.8/highlight.min.js"></script>
  <script src="https://cdn.bootcss.com/highlightjs-line-numbers.js/2.7.0/highlightjs-line-numbers.min.js"></script>
  <script>
    hljs.initHighlightingOnLoad();
    hljs.initLineNumbersOnLoad();
  </script>
</body>

5.效果展示

在后台添加Markdown格式文章,如下:
Django博客--5.让博客支持 Markdown 语法和代码高亮_第2张图片
运行服务器,效果如下:
Django博客--5.让博客支持 Markdown 语法和代码高亮_第3张图片

你可能感兴趣的:(Django--Blog)