From 735c79d78e9347a53e82f48721b55835ad50caf0 Mon Sep 17 00:00:00 2001 From: Paul Schilling Date: Thu, 8 Feb 2024 14:12:23 +0100 Subject: [PATCH] [#2030] Add support for custom italic, bold, bold-italic fonts --- src/open_inwoner/configurations/choices.py | 5 +- src/open_inwoner/configurations/constants.py | 7 -- .../migrations/0060_auto_20240208_1426.py | 72 +++++++++++++++++++ src/open_inwoner/configurations/models.py | 70 +++++++++++++++--- .../configurations/tests/test_upload.py | 25 +++++-- src/open_inwoner/scss/views/App.scss | 23 ++---- 6 files changed, 160 insertions(+), 42 deletions(-) delete mode 100644 src/open_inwoner/configurations/constants.py create mode 100644 src/open_inwoner/configurations/migrations/0060_auto_20240208_1426.py diff --git a/src/open_inwoner/configurations/choices.py b/src/open_inwoner/configurations/choices.py index d1b2d0b949..32ca043584 100644 --- a/src/open_inwoner/configurations/choices.py +++ b/src/open_inwoner/configurations/choices.py @@ -13,5 +13,8 @@ class OpenIDDisplayChoices(models.TextChoices): class CustomFontName(models.TextChoices): - body = _("text_body_font"), _("Text body font") + body = _("body_font_regular"), _("Text body font") + body_italic = _("body_font_italic"), _("Text body font italic") + body_bold = _("body_font_bold"), _("Text body font bold") + body_bold_italic = _("body_font_bold_italic"), _("Text body font bold italic") heading = _("heading_font"), _("Heading font") diff --git a/src/open_inwoner/configurations/constants.py b/src/open_inwoner/configurations/constants.py deleted file mode 100644 index 50349d679f..0000000000 --- a/src/open_inwoner/configurations/constants.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.db import models -from django.utils.translation import ugettext_lazy as _ - - -class FontFileName(models.TextChoices): - body = _("text_body_font"), _("Text body font") - heading = _("heading_font"), _("Heading font") diff --git a/src/open_inwoner/configurations/migrations/0060_auto_20240208_1426.py b/src/open_inwoner/configurations/migrations/0060_auto_20240208_1426.py new file mode 100644 index 0000000000..c981a5e530 --- /dev/null +++ b/src/open_inwoner/configurations/migrations/0060_auto_20240208_1426.py @@ -0,0 +1,72 @@ +# Generated by Django 3.2.23 on 2024-02-08 13:26 + +import django.core.validators +from django.db import migrations +import open_inwoner.configurations.models +import open_inwoner.utils.files + + +class Migration(migrations.Migration): + + dependencies = [ + ("configurations", "0059_merge_20240129_1645"), + ] + + operations = [ + migrations.RemoveField( + model_name="customfontset", + name="text_body_font", + ), + migrations.AddField( + model_name="customfontset", + name="body_font_bold", + field=open_inwoner.configurations.models.CustomFontField( + blank=True, + help_text="Upload bold text body font. TTF font types only.", + null=True, + storage=open_inwoner.utils.files.OverwriteStorage(), + upload_to=open_inwoner.configurations.models.CustomFontSet.update_filename_body_bold, + validators=[django.core.validators.FileExtensionValidator(["ttf"])], + verbose_name="Body font bold", + ), + ), + migrations.AddField( + model_name="customfontset", + name="body_font_bold_italic", + field=open_inwoner.configurations.models.CustomFontField( + blank=True, + help_text="Upload bold italic text body font. TTF font types only.", + null=True, + storage=open_inwoner.utils.files.OverwriteStorage(), + upload_to=open_inwoner.configurations.models.CustomFontSet.update_filename_body_bold_italic, + validators=[django.core.validators.FileExtensionValidator(["ttf"])], + verbose_name="Body font bold italic", + ), + ), + migrations.AddField( + model_name="customfontset", + name="body_font_italic", + field=open_inwoner.configurations.models.CustomFontField( + blank=True, + help_text="Upload italic text body font. TTF font types only.", + null=True, + storage=open_inwoner.utils.files.OverwriteStorage(), + upload_to=open_inwoner.configurations.models.CustomFontSet.update_filename_body_italic, + validators=[django.core.validators.FileExtensionValidator(["ttf"])], + verbose_name="Body font italic", + ), + ), + migrations.AddField( + model_name="customfontset", + name="body_font_regular", + field=open_inwoner.configurations.models.CustomFontField( + blank=True, + help_text="Upload regular text body font. TTF font types only.", + null=True, + storage=open_inwoner.utils.files.OverwriteStorage(), + upload_to=open_inwoner.configurations.models.CustomFontSet.update_filename_body, + validators=[django.core.validators.FileExtensionValidator(["ttf"])], + verbose_name="Body font regular", + ), + ), + ] diff --git a/src/open_inwoner/configurations/models.py b/src/open_inwoner/configurations/models.py index 15d74f6404..f98d455f69 100644 --- a/src/open_inwoner/configurations/models.py +++ b/src/open_inwoner/configurations/models.py @@ -618,6 +618,30 @@ def update_filename_body(self, filename: str) -> str: path="custom_fonts/", ) + def update_filename_body_italic(self, filename: str) -> str: + return CustomFontSet.update_filename( + self, + filename, + new_name=CustomFontName.body_italic, + path="custom_fonts/", + ) + + def update_filename_body_bold(self, filename: str) -> str: + return CustomFontSet.update_filename( + self, + filename, + new_name=CustomFontName.body_bold, + path="custom_fonts/", + ) + + def update_filename_body_bold_italic(self, filename: str) -> str: + return CustomFontSet.update_filename( + self, + filename, + new_name=CustomFontName.body_bold_italic, + path="custom_fonts/", + ) + def update_filename_heading(self, filename: str) -> str: return CustomFontSet.update_filename( self, @@ -626,31 +650,61 @@ def update_filename_heading(self, filename: str) -> str: path="custom_fonts/", ) + heading_font = CustomFontField( + verbose_name=_("Heading font"), + upload_to=update_filename_heading, + file_name=CustomFontName.heading, + storage=OverwriteStorage(), + validators=[FileExtensionValidator(["ttf"])], + blank=True, + null=True, + help_text=_("Upload heading font. TTF font types only."), + ) site_configuration = models.OneToOneField( SiteConfiguration, verbose_name=_("Configuration"), related_name="custom_fonts", on_delete=models.CASCADE, ) - text_body_font = CustomFontField( - verbose_name=_("Text body font"), + body_font_regular = CustomFontField( + verbose_name=_("Body font regular"), upload_to=update_filename_body, file_name=CustomFontName.body, storage=OverwriteStorage(), validators=[FileExtensionValidator(["ttf"])], blank=True, null=True, - help_text=_("Upload text body font. TTF font types only."), + help_text=_("Upload regular text body font. TTF font types only."), ) - heading_font = CustomFontField( - verbose_name=_("Heading font"), - upload_to=update_filename_heading, - file_name=CustomFontName.heading, + body_font_italic = CustomFontField( + verbose_name=_("Body font italic"), + upload_to=update_filename_body_italic, + file_name=CustomFontName.body_italic, storage=OverwriteStorage(), validators=[FileExtensionValidator(["ttf"])], blank=True, null=True, - help_text=_("Upload heading font. TTF font types only."), + help_text=_("Upload italic text body font. TTF font types only."), + ) + body_font_bold = CustomFontField( + verbose_name=_("Body font bold"), + upload_to=update_filename_body_bold, + file_name=CustomFontName.body_bold, + storage=OverwriteStorage(), + validators=[FileExtensionValidator(["ttf"])], + blank=True, + null=True, + help_text=_("Upload bold text body font. TTF font types only."), + ) + body_font_bold_italic = CustomFontField( + verbose_name=_("Body font bold italic"), + upload_to=update_filename_body_bold_italic, + file_name=CustomFontName.body_bold_italic, + storage=OverwriteStorage(), + validators=[FileExtensionValidator(["ttf"])], + blank=True, + null=True, + help_text=_("Upload bold italic text body font. TTF font types only."), ) diff --git a/src/open_inwoner/configurations/tests/test_upload.py b/src/open_inwoner/configurations/tests/test_upload.py index 973e5230e5..911f2e43c9 100644 --- a/src/open_inwoner/configurations/tests/test_upload.py +++ b/src/open_inwoner/configurations/tests/test_upload.py @@ -24,23 +24,34 @@ def setUp(self): def test_upload_font_correct_filetype(self): font_file = Upload("valid.ttf", b"content", content_type="font/ttf") self.form["name"] = "Test" - self.form["custom_fonts-0-text_body_font"] = font_file + self.form["custom_fonts-0-body_font_regular"] = font_file + self.form["custom_fonts-0-body_font_bold"] = font_file + self.form["custom_fonts-0-body_font_italic"] = font_file + self.form["custom_fonts-0-body_font_bold_italic"] = font_file self.form["custom_fonts-0-heading_font"] = font_file self.form.submit() custom_font_set = CustomFontSet.objects.first() - body_font = custom_font_set.text_body_font + body_font = custom_font_set.body_font_regular + body_font_bold = custom_font_set.body_font_bold + body_font_italic = custom_font_set.body_font_italic + body_font_bold_italic = custom_font_set.body_font_bold_italic heading_font = custom_font_set.heading_font - self.assertEqual(body_font.name, "custom_fonts/text_body_font.ttf") + self.assertEqual(body_font.name, "custom_fonts/body_font_regular.ttf") + self.assertEqual(body_font_bold.name, "custom_fonts/body_font_bold.ttf") + self.assertEqual(body_font_italic.name, "custom_fonts/body_font_italic.ttf") + self.assertEqual( + body_font_bold_italic.name, "custom_fonts/body_font_bold_italic.ttf" + ) self.assertEqual(heading_font.name, "custom_fonts/heading_font.ttf") # test file overwrite: upload again another_font_file = Upload( "valid_encore.ttf", b"content", content_type="font/ttf" ) - self.form["custom_fonts-0-text_body_font"] = another_font_file + self.form["custom_fonts-0-body_font_regular"] = another_font_file self.form["custom_fonts-0-heading_font"] = another_font_file self.form.submit() @@ -48,16 +59,16 @@ def test_upload_font_correct_filetype(self): self.assertEqual(len(CustomFontSet.objects.all()), 1) custom_font_set = CustomFontSet.objects.first() - body_font = custom_font_set.text_body_font + body_font = custom_font_set.body_font_regular heading_font = custom_font_set.heading_font - self.assertEqual(body_font.name, "custom_fonts/text_body_font.ttf") + self.assertEqual(body_font.name, "custom_fonts/body_font_regular.ttf") self.assertEqual(heading_font.name, "custom_fonts/heading_font.ttf") def test_upload_font_incorrect_filetype(self): font_file = Upload("invalid.svg", b"content", content_type="font/svg") self.form["name"] = "Test" - self.form["custom_fonts-0-text_body_font"] = font_file + self.form["custom_fonts-0-body_font_regular"] = font_file response = self.form.submit() diff --git a/src/open_inwoner/scss/views/App.scss b/src/open_inwoner/scss/views/App.scss index a1c17cf246..1bca847839 100644 --- a/src/open_inwoner/scss/views/App.scss +++ b/src/open_inwoner/scss/views/App.scss @@ -259,38 +259,23 @@ url('/static/fonts/ubuntu/Ubuntu-M.ttf') format('truetype'); } -@font-face { - font-family: 'Heading'; - font-weight: bold; - src: url('/media/custom_fonts/heading_font.ttf') format('truetype'), - url('/static/fonts/ubuntu/Ubuntu-M.ttf') format('truetype'); -} - -@font-face { - font-family: 'Heading'; - font-weight: bold; - font-style: italic; - src: url('/media/custom_fonts/heading_font.ttf') format('truetype'), - url('/static/fonts/ubuntu/Ubuntu-MI.ttf') format('truetype'); -} - @font-face { font-family: 'Body'; - src: url('/media/custom_fonts/text_body_font.ttf') format('truetype'), + src: url('/media/custom_fonts/body_font_regular.ttf') format('truetype'), url('/static/fonts/lato/Lato-Regular.ttf') format('truetype'); } @font-face { font-family: 'Body'; font-weight: bold; - src: url('/media/custom_fonts/heading_font.ttf') format('truetype'), + src: url('/media/custom_fonts/body_font_bold.ttf') format('truetype'), url('/static/fonts/lato/Lato-Bold.ttf') format('truetype'); } @font-face { font-family: 'Body'; font-style: italic; - src: url('/media/custom_fonts/heading_font.ttf') format('truetype'), + src: url('/media/custom_fonts/body_font_italic.ttf') format('truetype'), url('/static/fonts/lato/Lato-Italic.ttf') format('truetype'); } @@ -298,7 +283,7 @@ font-family: 'Body'; font-weight: bold; font-style: italic; - src: url('/media/custom_fonts/heading_font.ttf') format('truetype'), + src: url('/media/custom_fonts/body_font_bold_italic.ttf') format('truetype'), url('/static/fonts/lato/Lato-BoldItalic.ttf') format('truetype'); }