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.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)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
{% 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">
|
||||||
|
{% if page.table_of_contents %}
|
||||||
<div class="dropdown is-hoverable is-right">
|
<div class="dropdown is-hoverable is-right">
|
||||||
<div class="dropdown-trigger">
|
<div class="dropdown-trigger">
|
||||||
<button class="button is-radiusless" aria-haspopup="true" aria-controls="dropdown-menu">
|
<button class="button is-radiusless" aria-haspopup="true" aria-controls="dropdown-menu">
|
||||||
|
@ -28,11 +29,15 @@
|
||||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||||
<div class="dropdown-content menu">
|
<div class="dropdown-content menu">
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
<li><a>Dashboard</a></li>
|
{% for toc_item in page.table_of_contents %}
|
||||||
|
{% include "common/toc-item.html" %}
|
||||||
|
{% endfor %}
|
||||||
</ul>
|
</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>
|
||||||
|
|
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.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)
|
||||||
|
|
Loading…
Reference in a new issue