diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 20d8bca077..3c7d20b9cc 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -411,6 +411,10 @@ Your {event} team""")) 'default': '#8E44B3', 'type': str }, + 'primary_font': { + 'default': 'Open Sans', + 'type': str + }, 'presale_css_file': { 'default': None, 'type': str diff --git a/src/pretix/control/forms/event.py b/src/pretix/control/forms/event.py index 549d10c57f..bce55e7b05 100644 --- a/src/pretix/control/forms/event.py +++ b/src/pretix/control/forms/event.py @@ -13,6 +13,7 @@ from pretix.base.models import Event, Organizer, TaxRule from pretix.base.reldate import RelativeDateField, RelativeDateTimeField from pretix.control.forms import ExtFileField, SlugWidget from pretix.multidomain.urlreverse import build_absolute_uri +from pretix.presale.style import get_fonts class EventWizardFoundationForm(forms.Form): @@ -722,6 +723,13 @@ class DisplaySettingsForm(SettingsForm): help_text=_('If you provide a logo image, we will by default not show your events name and date ' 'in the page header. We will show your logo with a maximal height of 120 pixels.') ) + primary_font = forms.ChoiceField( + label=_('Font'), + choices=[ + ('Open Sans', 'Open Sans') + ], + help_text=_('Only respected by modern browsers.') + ) frontpage_text = I18nFormField( label=_("Frontpage text"), required=False, @@ -732,6 +740,12 @@ class DisplaySettingsForm(SettingsForm): required=False ) + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.fields['primary_font'].choices += [ + (a, a) for a in get_fonts() + ] + class TicketSettingsForm(SettingsForm): ticket_download = forms.BooleanField( diff --git a/src/pretix/control/templates/pretixcontrol/event/display.html b/src/pretix/control/templates/pretixcontrol/event/display.html index a62b48622f..f8c350b7db 100644 --- a/src/pretix/control/templates/pretixcontrol/event/display.html +++ b/src/pretix/control/templates/pretixcontrol/event/display.html @@ -8,6 +8,7 @@
{% trans "Display settings" %} {% bootstrap_field form.primary_color layout="horizontal" %} + {% bootstrap_field form.primary_font layout="horizontal" %} {% bootstrap_field form.logo_image layout="horizontal" %} {% bootstrap_field form.frontpage_text layout="horizontal" %} {% bootstrap_field form.show_variations_expanded layout="horizontal" %} diff --git a/src/pretix/plugins/ticketoutputpdf/signals.py b/src/pretix/plugins/ticketoutputpdf/signals.py index b3228883a9..c16b6d16e1 100644 --- a/src/pretix/plugins/ticketoutputpdf/signals.py +++ b/src/pretix/plugins/ticketoutputpdf/signals.py @@ -1,4 +1,4 @@ -from django.dispatch import Signal, receiver +from django.dispatch import receiver from django.template.loader import get_template from django.urls import resolve @@ -6,6 +6,9 @@ from pretix.base.signals import ( register_data_exporters, register_ticket_outputs, ) from pretix.control.signals import html_head +from pretix.presale.style import ( # NOQA: legacy import + get_fonts, register_fonts, +) @receiver(register_ticket_outputs, dispatch_uid="output_pdf") @@ -30,35 +33,3 @@ def html_head_presale(sender, request=None, **kwargs): }) else: return "" - - -register_fonts = Signal() -""" -Return a dictionaries of the following structure. Paths should be relative to static root. - -{ - "font name": { - "regular": { - "truetype": "….ttf", - "woff": "…", - "woff2": "…" - }, - "bold": { - ... - }, - "italic": { - ... - }, - "bolditalic": { - ... - } - } -} -""" - - -def get_fonts(): - f = {} - for recv, value in register_fonts.send(0): - f.update(value) - return f diff --git a/src/pretix/presale/style.py b/src/pretix/presale/style.py index 7d3639b2aa..878c4d8bb5 100644 --- a/src/pretix/presale/style.py +++ b/src/pretix/presale/style.py @@ -8,6 +8,7 @@ import sass from django.conf import settings from django.core.files.base import ContentFile from django.core.files.storage import default_storage +from django.dispatch import Signal from django.templatetags.static import static as _static from pretix.base.models import Event @@ -23,11 +24,6 @@ def regenerate_css(event_id: int): event = Event.objects.select_related('organizer').get(pk=event_id) sassdir = os.path.join(settings.STATIC_ROOT, 'pretixpresale/scss') - sassrules = [] - if event.settings.get('primary_color'): - sassrules.append('$brand-primary: {};'.format(event.settings.get('primary_color'))) - sassrules.append('@import "main.scss";') - def static(path): sp = _static(path) if not settings.MEDIA_URL.startswith("/") and sp.startswith("/"): @@ -41,6 +37,19 @@ def regenerate_css(event_id: int): sp = urljoin(settings.SITE_URL, sp) return '"{}"'.format(sp) + sassrules = [] + if event.settings.get('primary_color'): + sassrules.append('$brand-primary: {};'.format(event.settings.get('primary_color'))) + + font = event.settings.get('primary_font') + if font != 'Open Sans': + sassrules.append(get_font_stylesheet(font)) + sassrules.append('$font-family-sans-serif: "{}", "Open Sans", "OpenSans", "Helvetica Neue", Helvetica, Arial, sans-serif !default'.format( + font + )) + + sassrules.append('@import "main.scss";') + cf = dict(django_libsass.CUSTOM_FUNCTIONS) cf['static'] = static css = sass.compile( @@ -57,3 +66,62 @@ def regenerate_css(event_id: int): newname = default_storage.save(fname, ContentFile(css.encode('utf-8'))) event.settings.set('presale_css_file', newname) event.settings.set('presale_css_checksum', checksum) + + +register_fonts = Signal() +""" +Return a dictionaries of the following structure. Paths should be relative to static root. + +{ + "font name": { + "regular": { + "truetype": "….ttf", + "woff": "…", + "woff2": "…" + }, + "bold": { + ... + }, + "italic": { + ... + }, + "bolditalic": { + ... + } + } +} +""" + + +def get_fonts(): + f = {} + for recv, value in register_fonts.send(0): + f.update(value) + return f + + +def get_font_stylesheet(font_name): + stylesheet = [] + font = get_fonts()[font_name] + for sty, formats in font.items(): + stylesheet.append('@font-face { ') + stylesheet.append('font-family: "{}";'.format(font_name)) + if sty in ("italic", "bolditalic"): + stylesheet.append("font-style: italic;") + else: + stylesheet.append("font-style: normal;") + if sty in ("bold", "bolditalic"): + stylesheet.append("font-weight: bold;") + else: + stylesheet.append("font-weight: normal;") + + srcs = [] + if "woff2" in formats: + srcs.append("url(static('{}')) format('woff2')".format(formats['woff2'])) + if "woff" in formats: + srcs.append("url(static('{}')) format('woff')".format(formats['woff'])) + if "truetype" in formats: + srcs.append("url(static('{}')) format('truetype')".format(formats['truetype'])) + stylesheet.append("src: {};".format(", ".join(srcs))) + stylesheet.append("}") + return "\n".join(stylesheet)