diff --git a/static/src/scss/_listing.scss b/static/src/scss/_listing.scss index 123ac26..38d629e 100644 --- a/static/src/scss/_listing.scss +++ b/static/src/scss/_listing.scss @@ -38,3 +38,11 @@ width: 100%; } } + +.page-blog-bloglistpage { + .date-header { + font-size: $size-2; + font-weight: $weight-bold; + margin-bottom: 1rem; + } +} diff --git a/website/blog/models.py b/website/blog/models.py index 7ca03e0..dafd381 100644 --- a/website/blog/models.py +++ b/website/blog/models.py @@ -1,6 +1,7 @@ from typing import Any from django.db import models +from django.db.models.functions import TruncMonth from django.http.request import HttpRequest from django.utils import timezone from django.utils.functional import cached_property @@ -8,6 +9,7 @@ from modelcluster.contrib.taggit import ClusterTaggableManager from modelcluster.fields import ParentalKey from taggit.models import ItemBase, TagBase from wagtail.admin.panels import FieldPanel +from wagtail.query import PageQuerySet from website.common.models import BaseContentMixin, BasePage from website.common.utils import TocEntry @@ -20,20 +22,39 @@ class BlogListPage(BaseContentMixin, BasePage): # type: ignore[misc] @cached_property def reading_time(self) -> int: + """ + How does one read a list page? + """ return 0 @cached_property def table_of_contents(self) -> list[TocEntry]: - return [] + post_months = [ + dt.strftime("%Y-%m") + for dt in self.get_children() + .live() + .annotate(post_month=TruncMonth("date", output_field=models.DateField())) + .order_by("-post_month") + .values_list("post_month", flat=True) + .distinct() + ] + + return [TocEntry(post_month, post_month, 0, []) for post_month in post_months] + + def get_children(self) -> PageQuerySet: + """ + Since the children are always `BlogPostPage`, so juts use the specific queryset to save the `JOIN`. + """ + return BlogPostPage.objects.child_of(self) # type: ignore[attr-defined] def get_context(self, request: HttpRequest) -> dict: context = super().get_context(request) context["child_pages"] = ( self.get_children() .live() - .specific() .select_related("hero_image") .prefetch_related("tags") + .order_by("-date") ) return context diff --git a/website/blog/templates/blog/blog_list_page.html b/website/blog/templates/blog/blog_list_page.html index 0a583de..379dcd6 100644 --- a/website/blog/templates/blog/blog_list_page.html +++ b/website/blog/templates/blog/blog_list_page.html @@ -6,6 +6,12 @@
{% for page in child_pages %} + {% ifchanged %} + + {% endifchanged %} + {% include "common/listing-item.html" %} {% endfor %}