# SPDX-FileCopyrightText: 2024 Thomas Breitner <t.breitner@csl.mpg.de>
#
# SPDX-License-Identifier: EUPL-1.2
from django.db import models
from django.utils import timezone
from wagtail.search import index
from wagtail.models import Page, Orderable
from wagtail.fields import RichTextField, StreamField
from wagtail.admin.panels import (
FieldPanel,
InlinePanel,
MultiFieldPanel,
FieldRowPanel,
)
from modelcluster.fields import ParentalKey
from eucrim.article.models import (
ArticlePage,
ArticleIndexPage,
article_authors_prefetch,
)
from eucrim.issue.models import IssuePage, IssueIndexPage
from eucrim.news.models import NewsPage, NewsIndexPage
from eucrim.event.models import EventPage, EventIndexPage
from ..blocks import BaseStreamBlock
from ..abstracts import CarouselItem
[docs]
class HomePageCarouselItem(Orderable, CarouselItem):
page = ParentalKey("core.HomePage", related_name="carousel_items")
[docs]
class HomePage(Page):
parent_page_types = ["wagtailcore.Page"]
subpage_types = [
"StandardPage",
"article.ArticleIndexPage",
"association.AssociationIndexPage",
"issue.IssueIndexPage",
"news.NewsIndexPage",
"event.EventIndexPage",
"treaty.TreatyIndexPage",
"profile.ProfileIndexPage",
"procedure.ProcedureIndexPage",
]
max_count = 1
# TODO: This today instanciation seems weird
_today = timezone.now().date()
about = RichTextField(blank=True)
body = StreamField(
BaseStreamBlock,
verbose_name="Page body",
blank=True,
use_json_field=True,
)
last_articles_quantity = models.PositiveSmallIntegerField(
blank=True,
null=True,
default=5,
help_text="Show X latest articles on homepage (default: 5)",
)
last_editorials_quantity = models.PositiveSmallIntegerField(
blank=True,
null=True,
default=1,
help_text="Show X latest editorials on homepage (default: 1)",
)
last_news_quantity = models.PositiveSmallIntegerField(
blank=True,
null=True,
default=5,
help_text="Show X latest news on homepage (default: 5). In addition, "
"up to X featured news will be shown.",
)
last_featured_news_quantity = models.PositiveSmallIntegerField(
blank=True,
null=True,
default=3,
help_text="Show X latest featured news on homepage (default: 3) on top "
"of the standard news.",
)
last_issues_quantity = models.PositiveSmallIntegerField(
blank=True,
null=True,
default=5,
help_text="Show X latest issues on homepage (default: 5)",
)
last_events_quantity = models.PositiveSmallIntegerField(
blank=True,
null=True,
default=5,
help_text="Show X latest events on homepage (default: 5)",
)
[docs]
def get_event_index_page(self):
return EventIndexPage.objects.live().first()
[docs]
def get_news_index_page(self):
return NewsIndexPage.objects.live().first()
[docs]
def get_article_index_page(self):
return ArticleIndexPage.objects.live().first()
[docs]
def get_issue_index_page(self):
return IssueIndexPage.objects.live().first()
[docs]
def latest_articles(self):
return (
ArticlePage.objects.live()
.prefetch_related(article_authors_prefetch())
.exclude(article_type=ArticlePage.EDITORIAL)
.order_by("-publication_date")[: self.last_articles_quantity]
)
[docs]
def latest_editorials(self):
return (
ArticlePage.objects.live()
.prefetch_related(article_authors_prefetch())
.filter(article_type=ArticlePage.EDITORIAL)
.order_by("-publication_date")[: self.last_editorials_quantity]
)
[docs]
def latest_issues(self):
return (
IssuePage.objects.live()
.select_related("cover_image")
.order_by("-year", "-issue_number")[: self.last_issues_quantity]
)
[docs]
def latest_featured_news(self):
return NewsPage.featurednews_objects.all()[: self.last_featured_news_quantity]
[docs]
def latest_news(self):
return NewsPage.standardnews_objects.exclude(is_featured_news=True)[
: self.last_news_quantity
]
[docs]
def latest_events(self):
return (
EventPage.objects.live()
.filter(event_date_from__gte=self._today)
.order_by("event_date_from")[: self.last_events_quantity]
)
search_fields = Page.search_fields + [
index.SearchField("about"),
]
content_panels = Page.content_panels + [
FieldPanel("about", classname="full"),
FieldPanel("body"),
]
settings_panels = Page.settings_panels + [
FieldPanel("last_articles_quantity"),
FieldPanel("last_editorials_quantity"),
FieldPanel("last_news_quantity"),
FieldPanel("last_featured_news_quantity"),
FieldPanel("last_issues_quantity"),
FieldPanel("last_events_quantity"),
]
[docs]
class StandardPage(Page):
intro = models.TextField(help_text="Text to describe the page", blank=True)
body = StreamField(
BaseStreamBlock,
verbose_name="Page body",
blank=True,
use_json_field=True,
)
content_panels = Page.content_panels + [
FieldPanel("intro", classname="full"),
FieldPanel("body"),
]
promote_panels = Page.promote_panels
search_fields = Page.search_fields + [
index.SearchField("body"),
]
# The abstract model for abbreviations, complete with panels
[docs]
class Abbreviation(index.Indexed, models.Model):
term = models.CharField(max_length=255)
abbreviation = models.CharField(max_length=255)
panels = [
MultiFieldPanel(
[
FieldRowPanel(
[
FieldPanel("abbreviation"),
FieldPanel("term"),
]
),
]
),
]
# The real model which combines the abstract model, an
# Orderable helper class, and what amounts to a ForeignKey link
# to the model we want to add abbreviations to (AbbreviationIndexPage)
[docs]
class AbbreviationIndexPage(Page):
body = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel("body"),
InlinePanel("abbreviations", label="Abbreviations"),
]
search_fields = Page.search_fields + [
index.SearchField("body"),
]