Mix of Python and Django utility functions, classed etc.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

117 lines
3.8 KiB

from django.conf import settings
from django.db import models
from django.utils.html import strip_tags
from django.utils.text import normalize_newlines, Truncator
from django.utils.translation import gettext_lazy as _
from shared.multilingual.utils import i18n_fields_list
from ..functional import firstof
from ..text import slimdown
from .slugs import DowngradingSlugField
from ..conf import USE_TRANSLATABLE_FIELDS
if USE_TRANSLATABLE_FIELDS:
from shared.multilingual.utils.fields import (
TranslatableCharField,
TranslatableTextField
)
# TODO populate_from should use settings.LANGUAGE_CODE
# FIXME Wrong spelling!
SLUG_POPULATE_FROM = getattr(settings, 'SLUG_POPULATE_FROM', 'name_en')
else:
TranslatableCharField = models.CharField
TranslatableTextField = models.TextField
SLUG_POPULATE_FROM = 'name'
# TODO Make slimdown optional through settings
# TODO Leave window_title alone, do not slimdown
class PageTitlesBehaviour:
"""
Implements fallback behaviour.
"""
def __str__(self):
return strip_tags(slimdown(self.get_short_name()))
def get_title(self):
return self.get_first_title_line() or \
self.name
def get_short_name(self):
return getattr(self, 'short_name', '') or \
Truncator(self.name).words(5, truncate="...")
def get_first_title_line(self):
"""
First line of title field or self.name..
"""
return normalize_newlines(getattr(self, 'long_title', '') or '').partition("\n")[0]
def get_subtitle_lines(self):
"""
All but first line of the long title field.
"""
return normalize_newlines(getattr(self, 'long_title', '') or '').partition("\n")[2]
def get_window_title(self):
return firstof(
getattr(self, 'window_title', None),
strip_tags(slimdown(self.get_short_name())),
strip_tags(slimdown(self.get_first_title_line())),
)
PageTitlesFunctionMixin = PageTitlesBehaviour
class PageTitlesMixin(PageTitlesBehaviour, models.Model):
"""
A model mixin containg title and slug fields for models serving
as web pages with an URL.
name: Main naming field, all other fields besides `slug`
are optional.
short_name: For menus etc.
long_title: Long title, composed of title line (first line) and
subtitle (all other lines)
window_title: Browser window title, also for search engine's results
slug: URL name
"""
name = TranslatableCharField(_("Name"),
max_length=250)
sort_name = TranslatableCharField(_("Short Name"),
max_length=250, null=True, blank=True,
help_text=_("Optional, used for sorting."))
short_name = TranslatableCharField(_("Short Name"),
max_length=25, null=True, blank=True,
help_text=_("Optional, used for menus etc."))
long_title = TranslatableTextField(_("title/subtitle"),
null=True, blank=True, max_length=500,
help_text=_("Optional, long title for page content region. FIrst line is the title, other lines are the subtitle. Simplified Markdown."))
window_title = TranslatableCharField(_("window title"),
null=True, blank=True, max_length=300)
slug = DowngradingSlugField(_("URL-Name"), max_length=200,
populate_from=SLUG_POPULATE_FROM, unique_slug=True, blank=True)
class Meta:
abstract = True
ordering = ['sort_name', 'name']
class PageTitlesAdminMixin:
list_display = ['name', 'slug']
search_fields = ['name', 'short_name', 'long_title', 'window_title']
if USE_TRANSLATABLE_FIELDS:
search_fields = i18n_fields_list(search_fields)
prepopulated_fields = {
'slug': [SLUG_POPULATE_FROM]
}