From 9896f0e2887dc88d384f1b047d47f9e826746e57 Mon Sep 17 00:00:00 2001 From: Erik Stein Date: Fri, 17 Nov 2017 09:21:53 +0100 Subject: [PATCH] PageTitlesMixin with translated fields (optional); improved slimdown. --- shared/utils/models/pages.py | 84 ++++++++++++++++++++++++++++-------- shared/utils/text.py | 2 +- 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/shared/utils/models/pages.py b/shared/utils/models/pages.py index cdfd036..b6f9f19 100644 --- a/shared/utils/models/pages.py +++ b/shared/utils/models/pages.py @@ -2,14 +2,28 @@ from __future__ import unicode_literals # Erik Stein , 2017 - +from functools import reduce, partial +from django.conf import settings from django.db import models from django.utils.encoding import python_2_unicode_compatible +from django.utils.html import strip_tags from django.utils.text import normalize_newlines from django.utils.translation import ugettext_lazy as _ from ..fields import AutoSlugField from ..functional import firstof +from shared.utils.text import slimdown + + +USE_TRANSLATABLE_FIELDS = getattr(settings, 'CONTENT_USE_TRANSLATABLE_FIELDS', False) +# TODO Implement translatable AutoSlugField: USE_TRANSLATABLE_SLUG_FIELDS = getattr(settings, 'CONTENT_USE_TRANSLATABLE_SLUG_FIELDS', True) + + +if USE_TRANSLATABLE_FIELDS: + from shared.multilingual.utils.fields import TranslatableCharField, TranslatableTextField + +# TODO Make slimdown optional through settings +# TODO Leave window_title alone, do not slimdown # TODO Use translatable fields by default @@ -19,46 +33,80 @@ class PageTitlesMixin(models.Model): A model mixin containg title and slug field for models serving as website pages with an URL. """ - short_title = models.CharField(_("Name"), max_length=50) - slug = AutoSlugField(_("URL-Name"), max_length=200, populate_from='short_title', unique_slug=True) - title = models.TextField(_("Titel (Langform)"), null=True, blank=True, max_length=300) - window_title = models.CharField(_("Fenster-/Suchmaschinentitel"), null=True, blank=True, max_length=300) + # FIXME signals are not sent from abstract models, therefore AutoSlugField doesn't work + if USE_TRANSLATABLE_FIELDS: + short_title = TranslatableCharField(_("Name"), max_length=50) + title = TranslatableTextField(_("Titel (Langform)"), null=True, blank=True, max_length=300) + window_title = TranslatableCharField(_("Fenster-/Suchmaschinentitel"), null=True, blank=True, max_length=300) + # FIXME populate_from should use settings.LANGUAGE + slug = AutoSlugField(_("URL-Name"), max_length=200, populate_from='short_title_de', unique_slug=True, blank=True) + + else: + short_title = models.CharField(_("Name"), max_length=50) + title = models.TextField(_("Titel (Langform)"), null=True, blank=True, max_length=300) + window_title = models.CharField(_("Fenster-/Suchmaschinentitel"), null=True, blank=True, max_length=300) + slug = AutoSlugField(_("URL-Name"), max_length=200, populate_from='short_title', unique_slug=True, blank=True) class Meta: abstract = True def __str__(self): - return self.short_title + return strip_tags(slimdown(self.short_title)) def get_title(self): - return firstof( + return slimdown(firstof( self.title, self.short_title - ) + )) def get_window_title(self): - return firstof( - self.window_title, - self.short_title, - self.get_first_title_line(), - ) + return strip_tags(slimdown( + firstof( + self.window_title, + self.short_title, + self.get_first_title_line(), + ) + )) def get_first_title_line(self): """ First line of title field. """ - return normalize_newlines(self.get_title()).partition("\n")[0] + return slimdown( + normalize_newlines(self.get_title()).partition("\n")[0] + ) def get_subtitle_lines(self): """ All but first line of the long title field. """ - return normalize_newlines(self.title).partition("\n")[2] + return slimdown( + normalize_newlines(self.title).partition("\n")[2] + ) + + +# TODO Move to shared.multilingual or shared.utils.translation +def language_variations_for_field(language_codes, fields): + # TODO Check if field is translatable + return ["{}_{}".format(fields, s) for s in language_codes] + + +def language_variations_for_fields(fields, language_codes=None): + if not language_codes: + language_codes = [t[0] for t in settings.LANGUAGES] + f = partial(language_variations_for_field, language_codes) + return reduce(lambda x, y: x + y, map(f, fields)) class PageTitleAdminMixin(object): search_fields = ['short_title', 'title', 'window_title'] list_display = ['short_title', 'slug'] - prepopulated_fields = { - 'slug': ('short_title',), - } + if USE_TRANSLATABLE_FIELDS: + search_fields = language_variations_for_fields(search_fields) + prepopulated_fields = { + 'slug': ('short_title_en',), # FIXME Language suffix + } + else: + prepopulated_fields = { + 'slug': ('short_title',), # FIXME Language suffix + } diff --git a/shared/utils/text.py b/shared/utils/text.py index 1efe2fe..5a75431 100644 --- a/shared/utils/text.py +++ b/shared/utils/text.py @@ -69,7 +69,7 @@ def slimdown(text): """ i_pattern = re.compile(r"(\*)(.*?)\1") b_pattern = re.compile(r"(\*\*)(.*?)\1") - u_pattern = re.compile(r"(_)(.*?)\1") + u_pattern = re.compile(r"(__)(.*?)\1") text, n = re.subn(i_pattern, "\\2", text) text, n = re.subn(b_pattern, "\\2", text)