成都搜索优化整站优化,软件开发公司推荐,中企动力邮箱,网站建设的项目计划文章目录0.思路引导1.在文中插入目录2.在页面的任何地方插入目录3.美化标题的锚点 URL0.思路引导
Markdown 在解析内容的同时还可以自动提取整个内容的目录结构#xff0c;本文内容将从以下几个方面展开#xff1a; 1#xff09;在文中插入目录#xff1b; 2#xff09;在…
文章目录0.思路引导1.在文中插入目录2.在页面的任何地方插入目录3.美化标题的锚点 URL0.思路引导
Markdown 在解析内容的同时还可以自动提取整个内容的目录结构本文内容将从以下几个方面展开 1在文中插入目录 2在页面的任何地方插入目录 3美化标题的锚点 URL。
1.在文中插入目录
博客的 Post文章模型其中 body 是我们存储 Markdown 文本的字段
文件位置blog/models.py
from django.db import modelsclass Post(models.Model):# Other fields ...body models.TextField()再来回顾一下文章详情页的视图我们在 detail 视图函数中将 post 的 body 字段中的 Markdown 文本解析成了 HTML 文本然后传递给模板显示 文件位置blog/views.py
def detail(request, pk):post get_object_or_404(Post, pkpk)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() 方法把 post.body 中的 Markdown 文本解析成了 HTML 文本。同时我们还给该方法提供了一个 extensions 的额外参数。其中 markdown.extensions.toc 就是自动生成目录的拓展。
在渲染 Markdown 文本时加入了 toc 拓展后就可以在文中插入目录了。方法是在书写 Markdown 文本时在你想生成目录的地方插入 [TOC] 标记即可。
后台输入如下 效果展示如下
2.在页面的任何地方插入目录
上述方式的一个局限性就是只能通过 [TOC] 标记在文章内容中插入目录。如果想在页面的其它地方比如侧边栏插入一个目录该怎么做呢只需要稍微改动一下解析 Markdown 文本内容的方式即可。
以detail.py中的模板标签{% block toc %}为例其渲染的位置位于详情页的侧边栏现在想要在侧边栏中生成目录。
{% block toc %}
...
{% endblock toc %}需要修改的代码如下
文件位置blog/views.py
def detail(request, pk):post get_object_or_404(Post, pkpk)md markdown.Markdown(extensions[markdown.extensions.extra,markdown.extensions.codehilite,markdown.extensions.toc,])post.body md.convert(post.body)m re.search(rdiv classtoc\s*ul(.*)/ul\s*/div, md.toc, re.S)post.toc m.group(1) if m is not None else return render(request, blog/detail.html, context{post: post})文件位置detail.html
{% block toc %}{% if post.toc %}div classwidget widget-contenth3 classwidget-title文章目录/h3div classtocul{{ post.toc|safe }}/ul/div/div{% endif %}
{% endblock toc %}在这里我们没有直接用 markdown.markdown() 方法来渲染 post.body 中的内容而是先实例化了一个 markdown.Markdown 对象 md和 markdown.markdown() 方法一样也传入了 extensions 参数。
接着我们便使用该实例的 convert 方法将 post.body 中的 Markdown 文本解析成 HTML 文本。而一旦调用该方法后实例 md 就会多出一个 toc 属性这个属性的值就是内容的目录我们把 md.toc 的值通过整个表达式的处理赋给 post.toc 。
注意为了防止文章目录为空的情况使用正则表达式来测试 ul 标签中是否包裹有元素从而来确定是否存在目录。并使用新的模板标签 {% if %}来对post.toc做条件判断。
效果展示如下
3.美化标题的锚点 URL
文章内容的标题被设置了锚点点击目录中的某个标题页面就会跳到该文章内容中标题所在的位置这时候浏览器的 URL 显示的值可能不太美观比如像下面的样子 #1_1 就是锚点Markdown 在设置锚点时利用的是标题的值由于通常我们的标题都是中文Markdown 没法处理所以它就忽略的标题的值而是简单地在后面加了个1 _1 这样的锚点值。为了解决这一个问题需要修改一下传给 extentions 的参数其具体做法如下
文件位置blog/views.py
from django.utils.text import slugify
from markdown.extensions.toc import TocExtensiondef detail(request, pk):post get_object_or_404(Post, pkpk)md markdown.Markdown(extensions[markdown.extensions.extra,markdown.extensions.codehilite,# 记得在顶部引入 TocExtension 和 slugifyTocExtension(slugifyslugify),])post.body md.convert(post.body)m re.search(rdiv classtoc\s*ul(.*)/ul\s*/div, md.toc, re.S)post.toc m.group(1) if m is not None else return render(request, blog/detail.html, context{post: post})和之前不同的是extensions 中的 toc 拓展不再是字符串 markdown.extensions.toc 而是 TocExtension 的实例。
TocExtension 在实例化时其 slugify 参数可以接受一个函数这个函数将被用于处理标题的锚点值。
Markdown 内置的处理方法不能处理中文标题所以我们使用了 django.utils.text 中的 slugify 方法该方法可以很好地处理中文。
效果展示如下