diff --git a/src/pretix/base/services/mail.py b/src/pretix/base/services/mail.py index 74d5ec212b..4eb4b7ce72 100644 --- a/src/pretix/base/services/mail.py +++ b/src/pretix/base/services/mail.py @@ -82,6 +82,7 @@ def mail(email: str, subject: str, template: Union[str, LazyI18nString], 'invoice_company': '' }) body, body_md = render_mail(template, context) + subject = str(subject).format_map(context) sender = sender or (event.settings.get('mail_from') if event else settings.MAIL_FROM) subject = str(subject) diff --git a/src/pretix/plugins/sendmail/forms.py b/src/pretix/plugins/sendmail/forms.py index 1ccc3205e4..8cfa43a1b8 100644 --- a/src/pretix/plugins/sendmail/forms.py +++ b/src/pretix/plugins/sendmail/forms.py @@ -23,7 +23,11 @@ class MailForm(forms.Form): super().__init__(*args, **kwargs) self.fields['subject'] = I18nFormField( widget=I18nTextInput, required=True, - locales=event.settings.get('locales') + locales=event.settings.get('locales'), + help_text=_("Available placeholders: {expire_date}, {event}, {code}, {date}, {url}, " + "{invoice_name}, {invoice_company}"), + validators=[PlaceholderValidator(['{expire_date}', '{event}', '{code}', '{date}', '{url}', + '{invoice_name}', '{invoice_company}'])] ) self.fields['message'] = I18nFormField( widget=I18nTextarea, required=True, diff --git a/src/pretix/plugins/sendmail/views.py b/src/pretix/plugins/sendmail/views.py index 307ba14a4b..ea42617c6d 100644 --- a/src/pretix/plugins/sendmail/views.py +++ b/src/pretix/plugins/sendmail/views.py @@ -78,24 +78,33 @@ class SenderView(EventPermissionRequiredMixin, FormView): if self.request.POST.get("action") == "preview": for l in self.request.event.settings.locales: + with language(l): - self.output[l] = [] - self.output[l].append( - _('Subject: {subject}').format(subject=form.cleaned_data['subject'].localize(l))) - message = form.cleaned_data['message'].localize(l) - preview_text = message.format( - code='ORDER1234', - event=self.request.event.name, - date=date_format(now(), 'SHORT_DATE_FORMAT'), - expire_date=date_format(now() + timedelta(days=7), 'SHORT_DATE_FORMAT'), - url=build_absolute_uri(self.request.event, 'presale:event.order', kwargs={ + + context_dict = { + 'code': 'ORDER1234', + 'event': self.request.event.name, + 'date': date_format(now(), 'SHORT_DATE_FORMAT'), + 'expire_date': date_format(now() + timedelta(days=7), 'SHORT_DATE_FORMAT'), + 'url': build_absolute_uri(self.request.event, 'presale:event.order', kwargs={ 'order': 'ORDER1234', 'secret': 'longrandomsecretabcdef123456' }), - invoice_name=_('John Doe'), - invoice_company=_('Sample Company LLC'), - ) + 'invoice_name': _('John Doe'), + 'invoice_company': _('Sample Company LLC') + } + + self.output[l] = [] + + subject = form.cleaned_data['subject'].localize(l) + preview_subject = subject.format_map(context_dict) + self.output[l].append( + _('Subject: {subject}').format(subject=preview_subject)) + + message = form.cleaned_data['message'].localize(l) + preview_text = message.format_map(context_dict) self.output[l].append(preview_text) + return self.get(self.request, *self.args, **self.kwargs) for o in orders: diff --git a/src/tests/base/test_mail.py b/src/tests/base/test_mail.py index 082f2cc709..64eda03687 100644 --- a/src/tests/base/test_mail.py +++ b/src/tests/base/test_mail.py @@ -89,3 +89,13 @@ def test_send_mail_with_user_locale(env): assert len(djmail.outbox) == 1 assert djmail.outbox[0].subject == 'Benutzer' assert 'The language code used for rendering this e-mail is de.' in djmail.outbox[0].body + +@pytest.mark.django_db +def test_sendmail_placeholder(env): + djmail.outbox = [] + event, user, organizer = env + mail('dummy@dummy.dummy', '{event} Test subject', 'mailtest.txt', {"event": event}, event) + + assert len(djmail.outbox) == 1 + assert djmail.outbox[0].to == [user.email] + assert djmail.outbox[0].subject == 'Dummy Test subject' \ No newline at end of file diff --git a/src/tests/plugins/test_sendmail.py b/src/tests/plugins/test_sendmail.py index 5450c677e9..b9b03ac806 100644 --- a/src/tests/plugins/test_sendmail.py +++ b/src/tests/plugins/test_sendmail.py @@ -213,3 +213,20 @@ def test_sendmail_subevents(logged_in_client, sendmail_url, event, order): assert response.status_code == 200 assert 'Subevent FOO' in response.rendered_content + + +@pytest.mark.django_db +def test_sendmail_placeholder(logged_in_client, sendmail_url, event, order): + djmail.outbox = [] + response = logged_in_client.post(sendmail_url, + {'sendto': 'n', + 'subject_0': '{code} Test subject', + 'message_0': 'This is a test file for sending mails.', + 'action': 'preview' + }, + follow=True) + + assert response.status_code == 200 + assert 'ORDER1234' in response.rendered_content + + assert len(djmail.outbox) == 0