Build ToC from python
This commit is contained in:
parent
7b5d597d34
commit
6600b9ccb7
4 changed files with 60 additions and 17 deletions
|
@ -2,11 +2,13 @@ from typing import Any
|
|||
|
||||
from django.db import models
|
||||
from django.http.request import HttpRequest
|
||||
from django.utils.functional import classproperty
|
||||
from django.utils.functional import cached_property, classproperty
|
||||
from wagtail.admin.panels import FieldPanel
|
||||
from wagtail.images import get_image_model_string
|
||||
from wagtail.models import Page
|
||||
|
||||
from .utils import TocEntry, get_table_of_contents
|
||||
|
||||
|
||||
class BasePage(Page):
|
||||
show_in_menus_default = True
|
||||
|
@ -26,6 +28,10 @@ class BasePage(Page):
|
|||
"""
|
||||
return self.get_ancestors().reverse().exclude(depth__lte=2)
|
||||
|
||||
@cached_property
|
||||
def table_of_contents(self) -> list[TocEntry]:
|
||||
return get_table_of_contents()
|
||||
|
||||
|
||||
class BaseContentMixin(models.Model):
|
||||
subtitle = models.CharField(max_length=255, blank=True)
|
||||
|
|
|
@ -16,23 +16,28 @@
|
|||
{% endif %}
|
||||
</div>
|
||||
<div class="column is-narrow dropdown-wrapper is-hidden-touch is-grouped">
|
||||
<div class="dropdown is-hoverable is-right">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button is-radiusless" aria-haspopup="true" aria-controls="dropdown-menu">
|
||||
<span>Table of Contents</span>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-angle-down" aria-hidden="true"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content menu">
|
||||
<ul class="menu-list">
|
||||
<li><a>Dashboard</a></li>
|
||||
</ul>
|
||||
{% if page.table_of_contents %}
|
||||
<div class="dropdown is-hoverable is-right">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button is-radiusless" aria-haspopup="true" aria-controls="dropdown-menu">
|
||||
<span>Table of Contents</span>
|
||||
<span class="icon is-small">
|
||||
<i class="fas fa-angle-down" aria-hidden="true"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content menu">
|
||||
<ul class="menu-list">
|
||||
{% for toc_item in page.table_of_contents %}
|
||||
{% include "common/toc-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<button class="button is-radiusless" id="scroll-top">Top <i class="fas fa-angle-up ml-2" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
10
website/common/templates/common/toc-item.html
Normal file
10
website/common/templates/common/toc-item.html
Normal file
|
@ -0,0 +1,10 @@
|
|||
<li>
|
||||
<a href="#{{ toc_item.slug }}">{{ toc_item.title }}</a>
|
||||
{% if toc_item.children %}
|
||||
<ul>
|
||||
{% for toc_item in toc_item.children %}
|
||||
{% include "common/toc-item.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</li>
|
|
@ -1,4 +1,4 @@
|
|||
from typing import Type
|
||||
from typing import NamedTuple, Type
|
||||
|
||||
from django.conf import settings
|
||||
from django.http.request import HttpRequest
|
||||
|
@ -6,6 +6,28 @@ from wagtail.models import Page
|
|||
from wagtail.models import get_page_models as get_wagtail_page_models
|
||||
|
||||
|
||||
class TocEntry(NamedTuple):
|
||||
title: str
|
||||
slug: str
|
||||
children: list
|
||||
|
||||
|
||||
def get_table_of_contents() -> list[TocEntry]:
|
||||
return [
|
||||
TocEntry(
|
||||
"Title 1",
|
||||
"title-1",
|
||||
[
|
||||
TocEntry("Title 1.1", "title-11", []),
|
||||
TocEntry("Title 1.2", "title-12", []),
|
||||
TocEntry("Title 1.3", "title-13", []),
|
||||
],
|
||||
),
|
||||
TocEntry("Title 2", "title-2", []),
|
||||
TocEntry("Title 3", "title-3", []),
|
||||
]
|
||||
|
||||
|
||||
def get_page_models() -> list[Type[Page]]:
|
||||
page_models = get_wagtail_page_models().copy()
|
||||
page_models.remove(Page)
|
||||
|
|
Loading…
Reference in a new issue