Django应用-5-给文章页添加自动生成的目录

当文章内容比较长的时候,给页面生成一个目录,帮助读者快速了解文章框架、迅速定位关注的内容是非常必要的,生成目录有多种方式:

  • 如果页面内容是通过markdown生成的,可以直接用markdown组件的toc拓展生成。
  • 如果页面内容不是markdown,而是标准的html
    • 可以通过正则表达式,提取出页面的标题内容
    • 也可以通过通过beautifulsoap插件,提取出内容,并为原来的HTML增加标签。

1、通过正则表达式提取页面标题内容

实现思路:通过re.findall,找到所有的标题元素,之后对每个标题进行遍历,拼装成带有链接的list元素,传给前端页面,实现代码如下:

# 通过正则找到标题
heads = re.findall(r"<h[1,2,3,4,5]>.*?</h[1,2,3,4,5]>",body_text)
re_heads=[]
# 对标题进行循环,生成链接
for head in heads:
    head_name = re.findall(r"<h[1,2,3,4,5]>(.*?)</h[1,2,3,4,5]>",head)[0]
    head = re.sub('<h2>','<li class="title-2"><a href="#' + head_name + '" class="link-secondary">', head)
    head = re.sub('<h3>','<li class="title-3"><a href="#' + head_name + '" class="link-secondary">', head)
    head = re.sub('<h4>','<li class="title-4"><a href="#' + head_name + '" class="link-secondary">', head)
    head = re.sub('</h[2,3,4]>', '</a></li>', head)
    re_heads.append(head)
context['re_heads'] = re_heads

在前端页面,展示拼装成的目录元素:

<div class="right-bar position-sticky">
   <p>目录</p>
   <ul class="agenda">
       {% for h in re_heads%}
            {{ h|richtext }}
       {% endfor %}
    </ul>
</div>

样式表如下:

.agenda {
            margin:0;
            margin-block-start: 0;
            padding-left: 0;
        }
        .agenda li{
            list-style: none;
            line-height:2em;
            text-indent: 0em;
        }
        .agenda li.title-3{
            font-size: 0.9rem;
            text-indent: 0.9rem;
        }
        .agenda li a{
            text-decoration: none;
            color:rgb(100 106 115);
        

2、通过beautifulsoap生成

首先,安装beautifulsoap:

pip3 install beautifulsoup4
pip3 install html5lib

接下来,处理:

# 生成目录
        # 获取文本内容
        body_text = self.blog_body
        # 对原文内容进行处理,并生成目录
        soup = BeautifulSoup(body_text)
        heads =soup.find_all(["h1", "h2", "h3", "h4"])
        agenda = soup.new_tag("ul")
        agenda['class'] = "agenda"
        for head in heads:
            head_name = ''
            for string in head.strings:
                head_name = head_name + string
            tag_name = head.name
            # 在原文中增加锚点
            anchor = soup.new_tag("a")
            anchor['name'] = head.string
            head.insert_before(anchor)
            # 生成目录
            agenda_item = soup.new_tag("li")
            agenda_item['class'] = tag_name
            agenda_item_href = soup.new_tag("a")
            agenda_item_href['href'] = "#" + head_name
            agenda_item_href['class'] = "link-secondary"
            agenda_item_href.string = head_name
            agenda_item.append(agenda_item_href)
            agenda.append(agenda_item)
        content_pretty = soup.prettify()
        agenda = agenda.prettify()
        # 返回参数
        context['agenda'] = agenda
				context['content_pretty'] = content_pretty

beautiful soap文档链接:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/#

3、Markdown生成toc目录

网上此类案例很多,本文不再赘述。

最终样式如下所示:

Leave a comment

Your email address will not be published. Required fields are marked *