Django从零搭建我的博客 | 使用Markdown语法书写文章整合

原文章地址: EOSONES博客

在技术博客文章详情页面中,最受程序员欢迎的便捷简约排版方式莫属Markdown,本文主要介绍Markdown格式在博文的前端显示及代码高亮,和Django后台admin中编辑博文时Markdown的实时预览。javascript

前端显示

一、安装Markdown

Markdown是一种轻量级的标记语言,它容许人们“使用易读易写的纯文本格式编写文档,而后转换成有效的或者HTML文档。关于 Markdown语法看这里。 Python插件markdown默认支持标准的markdown语法,但标准语法里代码块须要每行前空4个空格才能识别。推荐使用 Python-markdown2 ,它是python-markdown的升级版,支持GFM式(GFM 是 Github 拓展的基于 Markdown 的一种纯文本的书写格式)的markdown书写格式。容许使用```包裹代码块。css

打开CMD,进入虚拟环境html

pip install markdown

二、使用Markdown

为了将Markdown语法书写的文章渲染为HTML文本,首先改写 Storm / views.py 的 文章处理类 ArticleDetailView:前端

#Storm / views.py 

from Storm import models
from django.shortcuts import render, get_object_or_404
from django.views.generic import DetailView #从数据库获取模型的一条记录数据DetailView
import markdown #导入markdown
from django.utils.text import slugify
from markdown.extensions.toc import TocExtension

#文章详情页类处理
class ArticleDetailView(DetailView):
    model=models.Article
    template_name = 'article.html' 
    context_object_name = 'article' 

    def get(self, request, *args, **kwargs):
       # ···

    def get_object(self, queryset=None):
    # 覆写 get_object 方法的目的是由于须要对 article 的 body 值进行渲染
    # 将markdown语法渲染成html样式
    article.body = markdown.markdown(article.body,
        extensions=[
        # 包含 缩写、表格等经常使用扩展
        'markdown.extensions.extra',
        # 语法高亮扩展
        'markdown.extensions.codehilite',
        #容许咱们自动生成目录
         'markdown.extensions.toc',
        ])
    return article

代码中markdown.markdown语法接收两个参数:第一个参数是须要渲染的文章正文article.body;第二个参数载入了经常使用的语法扩展,markdown.extensions.extra中包括了缩写、表格、语法高亮、自动生成目录等扩展。 而后,修改前端模板有关文章正文的部分:java

#templates/article.html

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

safe 是 Django 模板系统中的过滤器(Filter),Django出于安全的考虑,会将输出的HTML代码进行转义,这使得article.body中渲染的HTML文本没法正常显示。而|safe就相似给article.body贴了一个标签,表示这一段字符不须要进行转义了。 启动服务器,在后台中新录入一条用markdown语法书写的文章,内容以下:python

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

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

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

···
def detail(request, id):
 article = ArticlePost.objects.get(id=id)
 # 将markdown语法渲染成html样式
 article.body = markdown.markdown(article.body,
  extensions=[
      # 包含 缩写、表格等经常使用扩展
     'markdown.extensions.extra',
      # 语法高亮扩展
      'markdown.extensions.codehilite',
      #容许咱们自动生成目录
       'markdown.extensions.toc',
  ])
 context = { 'article': article }
 return render(request, 'article/detail.html', context)
···

此时能够解析出Markdown的原生格式了,但后续须要代码高亮及其格式的美化。git

三、代码高亮

Pygments是一种通用语法高亮显示器,能够帮助咱们自动生成美化代码块的样式文件。(插件highlight.js也比较经常使用) 从新打开命令行窗口,进入虚拟环境安装Pygments:程序员

pip install Pygments

安装完成后Pygments在后台为咱们作了不少事,它把高亮的一些语法转为css样式,把代码分红了一个一个单词,在前端页面,直接右键查看源码就能看到了。须要注意的是为了让Pygments正确识别分割代码块,在后台编辑输入代码块时,建议在```包裹后加上代码种类,以下:github

···Python
   代码块
···

而后咱们须要生成高亮样式,在命令行中进入static目录中的css文件中,输入Pygments指令后回车:数据库

pygmentize -S default -f html -a .codehilite > default.css
  1. -a .codehilite指全部css选择器都具备.codehilite这一优先选择器
  2. -S default就是指定所须要的样式,Pygments还内置了不少其余的样式, 官网样式
  3. > default.css将内容输出到default.css文件中 这里有一点须要注意, 生成命令中的 -a 参数须要与真实页面中的 CSS Selector 相对应,即.codehilite这个字段在有些版本中应写为.highlight。若是后面的代码高亮无效,极可能是这里出了问题。 此时在css目录中是否自动生成了一个叫default.css的文件,接下来咱们在 content-base.html 中引用这个文件,同时引入bootstrapc框架会使排版格式更加美观。
#templates/content-base.html
  <head>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <!-- 引入monikai.css -->
    <link rel="stylesheet" href="{% static 'css/default.css' %}">
  </head>

完成以上步骤后先退出服务器而后从新 runserver,顺利的话看到以下:

最后,还能够对markdown文本的总体样式进行自定义修改,为了避免影响页面其余地方,最好在包裹文章的标签中加个class标识。

#例如修改代码框

.markdown pre {
    padding: 1em;
    border: none;
    line-height: 1.45;
    max-height: 35em;
    position: relative;
    background: url(/static/images/blueprint.png) #F6F6F6;
}
#...
<p class=‘markdown’>{{ article.body|safe }}</p>

四、自动生成文章目录

在使用markdown的步骤中,咱们在 Storm / views.py 函数中的markdown.extensions.extra参数中加入了自动生成目录插件,在输入博文时,在须要加入标题的位置加入[TOC]标记便可,在前端文章中就能 看到[TOC]标记的地方被内容的目录替换了。 上述方式的一个局限局限性就是只能经过 [TOC] 标记在文章内容中插入目录,若是我想在页面的其它地方,需修改:

#Storm/views.py

from Storm import models
from django.shortcuts import render, get_object_or_404
from django.views.generic import DetailView #从数据库获取模型的一条记录数据DetailView
import markdown #导入markdown
from django.utils.text import slugify
from markdown.extensions.toc import TocExtension

#文章详情页类处理
class ArticleDetailView(DetailView):
    model=models.Article
    template_name = 'article.html' 
    context_object_name = 'article' 

    def get(self, request, *args, **kwargs):
       # ···

    def get_object(self, queryset=None):
      # 覆写 get_object 方法的目的是由于须要对 article 的 body 值进行渲染,用model的方法
      article = super(ArticleDetailView, self).get_object(queryset=None)
      md = markdown.Markdown(extensions=[
            'markdown.extensions.extra',
            'markdown.extensions.codehilite',
            #美化点击目录时的url显示模块
            TocExtension(slugify=slugify),
       ])
       #md实例的convert方法将markdown转为html
       article.body = md.convert(article.body)
       #实例 md 就会多出一个 toc 属性
       article.toc = md.toc
       return article

注意文章 article 实例自己是没有 md 属性的,利用动态语言的特性咱们给它动态添加了 md 属性。此时在前端模板的任何位置就能够进行渲染目录。

<div>
    <p>目录</p>
    {{ article.toc|safe }}
    <a href="javascript:void(0);" class="top">返回顶部</a>
 </div>

Admin中编辑及预览

在django中有很好的插件来让咱们快速完成 django admin 后台中博文的编辑及实时预览—django-mdeditor

一、安装配置

打开CMD,进入虚拟环境

pip install django-mdeditor

在项目的settings.py的INSTALLED_APPS中添加’mdeditor’,

INSTALLED_APPS = [
    #...
    "mdeditor",
    #...
]

配置好上传目录media文件夹

#Myblog/settings.py

# 媒体文件专属参数设置(须要加url识别才能访问)
MEDIA_URL = "/media/" # 媒体文件别名(相对路径) 和 绝对路径
MEDIA_ROOT = (
    os.path.join(BASE_DIR, 'media')
)

最后将mdeditor添加到项目的url中:

#Myblog/urls.py

urlpatterns = [
    #...
    re_path(r'mdeditor/', include('mdeditor.urls')),
]

在咱们的 Storm/models.py 下的文章模型中重写 body 字段

from mdeditor.fields import MDTextField

# 文章
class Article(models.Model):
    #...
    # 文章内容
    body = MDTextField(verbose_name='文章内容')
    #...

注意在 Storm/admin.py 中配置以便后台显示 ,而后迁移数据库

python manage.py makemigrations
python manage.py migrate

二、查看效果

运行项目,进入后台admin,进入博文的编辑页面,编辑Markdown及实时预览。 最后的问题就是如何作到Django admin中的预览效果与前端一致,由于咱们的样式配置不一样,Django插件mdeditor的Markdown样式位置通常在虚拟环境下的 Lib\site-packages\mdeditor\static\mdeditor\css 中的editormd.css里,能够修改为前端的样式文件,或者将前端引入这个样式,并在文章包裹的标签中加入class="markdown-body"

参考:追梦任务 | Markdown 自动生成文章目录 | Django搭建我的博客:使用Markdown语法书写文章

相关文章
相关标签/搜索