import logging from django.db import models from django.utils import timezone from wagtail.admin.edit_handlers import ( FieldPanel, MultiFieldPanel, PublishingPanel, StreamFieldPanel, ) from wagtail.core.fields import StreamField from wagtail.core.models import Page from wagtail.images.edit_handlers import ImageChooserPanel from shared.blocks import DEFAULT_CONTENT_BLOCKS, MenuItemBlock, MenuParentBlock logger = logging.getLogger(__name__) class SubpageMixin: """Must be used in class definition before MetadataPageMixin!""" @property def root_page(self): if not hasattr(self, "_root_page"): # vypada to hackove ale lze takto pouzit: dle dokumentace get_ancestors # vraci stranky v poradi od rootu, tedy domovska stranka je druha v poradi self._root_page = self.get_ancestors().specific()[1] return self._root_page def get_meta_image(self): return self.search_image or self.root_page.get_meta_image() class ArticleMixin(models.Model): """ Common fields for articles. Must be used in class definition before MetadataPageMixin! If you want to tag articles, add tags as `tags` field in article page model. """ ### FIELDS content = StreamField( DEFAULT_CONTENT_BLOCKS, verbose_name="Článek", blank=True, ) date = models.DateField("datum", default=timezone.now) perex = models.TextField("perex") author = models.CharField("autor", max_length=250, blank=True, null=True) image = models.ForeignKey( "wagtailimages.Image", on_delete=models.PROTECT, blank=True, null=True, verbose_name="obrázek", ) ### PANELS content_panels = Page.content_panels + [ FieldPanel("date"), FieldPanel("perex"), StreamFieldPanel("content"), FieldPanel("author"), ImageChooserPanel("image"), ] settings_panels = [PublishingPanel()] class Meta: abstract = True @classmethod def has_tags(cls): try: cls._meta.get_field("tags") except models.FieldDoesNotExist: return False return True def tag_filter_page(self): """Page used for filtering by tags in url like `?tag=foo`.""" return self.get_parent() def get_meta_image(self): if hasattr(self, "search_image") and self.search_image: return self.search_image return self.image def get_meta_description(self): if hasattr(self, "search_description") and self.search_description: return self.search_description return self.perex class MenuMixin(Page): menu = StreamField( [("menu_item", MenuItemBlock()), ("menu_parent", MenuParentBlock())], verbose_name="Menu", blank=True, ) menu_panels = [ MultiFieldPanel( [ StreamFieldPanel("menu"), ], heading="Menu Options", ), ] class Meta: abstract = True class ExtendedMetadataHomePageMixin(models.Model): """Use for site home page to define metadata title suffix. Must be used in class definition before MetadataPageMixin! """ title_suffix = models.CharField( "Přípona titulku stránky", max_length=100, blank=True, null=True, help_text="Umožňuje přidat příponu k základnímu titulku stránky. Pokud " "je např. titulek stránky pojmenovaný 'Kontakt' a do přípony vyplníte " "'MS Pardubice | Piráti', výsledný titulek bude " "'Kontakt | MS Pardubice | Piráti'. Pokud příponu nevyplníte, použije " "se název webu.", ) class Meta: abstract = True def get_meta_title_suffix(self): if self.title_suffix: return self.title_suffix if hasattr(super(), "get_meta_title"): return super().get_meta_title() return self.get_site().site_name def get_meta_title(self): title = super().get_meta_title() suffix = self.get_meta_title_suffix() # Covers scenario when title_suffix is not set and evaluates to super().get_meta_title() value. # Rather than having MS Pardubice | MS Pardubice, just use MS Pardubice alone. if title != suffix: return f"{super().get_meta_title()} | {self.get_meta_title_suffix()}" return title class ExtendedMetadataPageMixin(models.Model): """Use for pages except for home page to use shared metadata title suffix. There are few rules on how to use this: - Do not forget to list ExtendedMetadataHomePageMixin among ancestors of the related HomePage class. - Must be used in class definition before MetadataPageMixin. - Expects SubpageMixin or equivalent exposing `root_page` property to be used for the page too. """ class Meta: abstract = True def get_meta_title_suffix(self): if not hasattr(self, "root_page"): logger.warning( "Using `ExtendedMetadataPageMixin` without `SubpageMixin` for %s", repr(self), ) return None if not hasattr(self.root_page, "get_meta_title_suffix"): logger.warning( "Using `ExtendedMetadataPageMixin` without `ExtendedMetadataHomePageMixin` on the root page for %s", repr(self), ) return None return self.root_page.get_meta_title_suffix() def get_meta_title(self): suffix = self.get_meta_title_suffix() if not suffix: return super().get_meta_title() return f"{super().get_meta_title()} | {self.get_meta_title_suffix()}"