-
feat: improve meta tag fallback handling to provide more meaningful values when not overriden manually
feat: improve meta tag fallback handling to provide more meaningful values when not overriden manually
models.py 5.65 KiB
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()}"