Build ToC from python

This commit is contained in:
Jake Howard 2022-06-19 20:13:19 +01:00
parent 7b5d597d34
commit 6600b9ccb7
Signed by: jake
GPG key ID: 57AFB45680EDD477
4 changed files with 60 additions and 17 deletions

View file

@ -2,11 +2,13 @@ from typing import Any
from django.db import models from django.db import models
from django.http.request import HttpRequest 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.admin.panels import FieldPanel
from wagtail.images import get_image_model_string from wagtail.images import get_image_model_string
from wagtail.models import Page from wagtail.models import Page
from .utils import TocEntry, get_table_of_contents
class BasePage(Page): class BasePage(Page):
show_in_menus_default = True show_in_menus_default = True
@ -26,6 +28,10 @@ class BasePage(Page):
""" """
return self.get_ancestors().reverse().exclude(depth__lte=2) 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): class BaseContentMixin(models.Model):
subtitle = models.CharField(max_length=255, blank=True) subtitle = models.CharField(max_length=255, blank=True)

View file

@ -16,23 +16,28 @@
{% endif %} {% endif %}
</div> </div>
<div class="column is-narrow dropdown-wrapper is-hidden-touch is-grouped"> <div class="column is-narrow dropdown-wrapper is-hidden-touch is-grouped">
<div class="dropdown is-hoverable is-right"> {% if page.table_of_contents %}
<div class="dropdown-trigger"> <div class="dropdown is-hoverable is-right">
<button class="button is-radiusless" aria-haspopup="true" aria-controls="dropdown-menu"> <div class="dropdown-trigger">
<span>Table of Contents</span> <button class="button is-radiusless" aria-haspopup="true" aria-controls="dropdown-menu">
<span class="icon is-small"> <span>Table of Contents</span>
<i class="fas fa-angle-down" aria-hidden="true"></i> <span class="icon is-small">
</span> <i class="fas fa-angle-down" aria-hidden="true"></i>
</button> </span>
</div> </button>
<div class="dropdown-menu" id="dropdown-menu" role="menu"> </div>
<div class="dropdown-content menu"> <div class="dropdown-menu" id="dropdown-menu" role="menu">
<ul class="menu-list"> <div class="dropdown-content menu">
<li><a>Dashboard</a></li> <ul class="menu-list">
</ul> {% for toc_item in page.table_of_contents %}
{% include "common/toc-item.html" %}
{% endfor %}
</ul>
</div>
</div> </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> <button class="button is-radiusless" id="scroll-top">Top <i class="fas fa-angle-up ml-2" aria-hidden="true"></i></button>
</div> </div>
</div> </div>

View 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>

View file

@ -1,4 +1,4 @@
from typing import Type from typing import NamedTuple, Type
from django.conf import settings from django.conf import settings
from django.http.request import HttpRequest 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 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]]: def get_page_models() -> list[Type[Page]]:
page_models = get_wagtail_page_models().copy() page_models = get_wagtail_page_models().copy()
page_models.remove(Page) page_models.remove(Page)