| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
- from django.db import models
- from wagtail.admin.panels import FieldPanel
- from wagtail.api import APIField
- from wagtail.blocks import ChoiceBlock, StructBlock, StructValue, URLBlock
- from wagtail.fields import StreamField
- from wagtail.models import Page
- from wagtail.search import index
- from bakerydemo.base.blocks import BaseStreamBlock
- from ..breads.models import Country
- class SocialMediaValue(StructValue):
- def get_platform_label(self):
- return dict(self.block.child_blocks["platform"].field.choices).get(
- self["platform"]
- )
- class SocialMediaBlock(StructBlock):
- """
- Block for social media links
- """
- platform = ChoiceBlock(
- choices=[
- ("github", "GitHub"),
- ("twitter", "Twitter/X"),
- ("linkedin", "LinkedIn"),
- ("instagram", "Instagram"),
- ("facebook", "Facebook"),
- ("mastodon", "Mastodon"),
- ("website", "Personal Website"),
- ],
- help_text="Select the social media platform",
- )
- url = URLBlock(
- label="URL",
- help_text="Full URL to your profile (e.g., https://github.com/username)",
- )
- class Meta:
- icon = "link"
- label = "Social Media Link"
- value_class = SocialMediaValue
- class PersonPage(Page):
- """
- Detail view for a specific person
- """
- introduction = models.TextField(help_text="Text to describe the page", blank=True)
- image = models.ForeignKey(
- "wagtailimages.Image",
- null=True,
- blank=True,
- on_delete=models.SET_NULL,
- related_name="+",
- help_text="Landscape mode only; horizontal width between 1000px and 3000px.",
- )
- body = StreamField(BaseStreamBlock(), verbose_name="Page body", blank=True)
- location = models.ForeignKey(
- Country,
- on_delete=models.SET_NULL,
- null=True,
- blank=True,
- )
- social_links = StreamField(
- [("social", SocialMediaBlock())],
- blank=True,
- help_text="Add social media profiles",
- )
- content_panels = Page.content_panels + [
- FieldPanel("introduction"),
- FieldPanel("image"),
- FieldPanel("location"),
- FieldPanel("body"),
- FieldPanel("social_links"),
- ]
- search_fields = Page.search_fields + [
- index.SearchField("introduction"),
- index.SearchField("body"),
- ]
- parent_page_types = ["PeopleIndexPage"]
- api_fields = [
- APIField("introduction"),
- APIField("image"),
- APIField("body"),
- APIField("location"),
- APIField("social_links"),
- ]
- def get_context(self, request):
- context = super(PersonPage, self).get_context(request)
- platform_block = SocialMediaBlock().child_blocks["platform"]
- platform_labels = dict(platform_block.field.choices)
- social_links = [
- {
- "platform": link.value["platform"],
- "label": platform_labels.get(
- link.value["platform"], link.value["platform"]
- ),
- "url": link.value["url"],
- }
- for link in (self.social_links or [])
- ]
- context["social_links"] = social_links
- return context
- class PeopleIndexPage(Page):
- """
- Index page for people.
- Lists all People objects with pagination.
- """
- introduction = models.TextField(help_text="Text to describe the page", blank=True)
- image = models.ForeignKey(
- "wagtailimages.Image",
- null=True,
- blank=True,
- on_delete=models.SET_NULL,
- related_name="+",
- help_text="Landscape mode only; horizontal width between 1000px and 3000px.",
- )
- content_panels = Page.content_panels + [
- FieldPanel("introduction"),
- FieldPanel("image"),
- ]
- # Can only have PersonPage children
- subpage_types = ["PersonPage"]
- api_fields = [
- APIField("introduction"),
- APIField("image"),
- ]
- # Returns a queryset of PersonPage objects that are live, that are direct
- # descendants of this index page with most recent first
- def get_people(self):
- return (
- PersonPage.objects.live()
- .descendant_of(self)
- .order_by("-first_published_at")
- )
- # Allows child objects (e.g. PersonPage objects) to be accessible via the
- # template
- def children(self):
- return self.get_children().specific().live()
- # Pagination for the index page
- def paginate(self, request, *args):
- page = request.GET.get("page")
- paginator = Paginator(self.get_people(), 12)
- try:
- pages = paginator.page(page)
- except PageNotAnInteger:
- pages = paginator.page(1)
- except EmptyPage:
- pages = paginator.page(paginator.num_pages)
- return pages
- # Returns the above to the get_context method that is used to populate the
- # template
- def get_context(self, request):
- context = super(PeopleIndexPage, self).get_context(request)
- # PersonPage objects (get_people) are passed through pagination
- people = self.paginate(request, self.get_people())
- context["people"] = people
- return context
|