forked from CGM_Public/pretix_original
Add the option to introduce rich-text placeholders (#4657)
* Add the option to introduce rich-text placeholders * Add tests in test_format * Add some css * Block vs inline * Some fixed css * Update src/pretix/control/forms/event.py Co-authored-by: Mira <weller@rami.io> * Add missing docstring prat --------- Co-authored-by: Mira <weller@rami.io>
This commit is contained in:
@@ -1385,7 +1385,7 @@ class MailSettingsForm(FormPlaceholderMixin, SettingsForm):
|
||||
self.event.meta_values_cached = self.event.meta_values.select_related('property').all()
|
||||
|
||||
for k, v in self.base_context.items():
|
||||
self._set_field_placeholders(k, v)
|
||||
self._set_field_placeholders(k, v, rich=k.startswith('mail_text_'))
|
||||
|
||||
for k, v in list(self.fields.items()):
|
||||
if k.endswith('_attendee') and not event.settings.attendee_emails_asked:
|
||||
|
||||
@@ -62,7 +62,7 @@ from django.http import (
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import escape
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.http import url_has_allowed_host_and_scheme
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext, gettext_lazy as _, gettext_noop
|
||||
@@ -100,9 +100,12 @@ from ...base.models.items import (
|
||||
Item, ItemCategory, ItemMetaProperty, Question, Quota,
|
||||
)
|
||||
from ...base.services.mail import prefix_subject
|
||||
from ...base.services.placeholders import get_sample_context
|
||||
from ...base.settings import LazyI18nStringList
|
||||
from ...helpers.compat import CompatDeleteView
|
||||
from ...helpers.format import format_map
|
||||
from ...helpers.format import (
|
||||
PlainHtmlAlternativeString, SafeFormatter, format_map,
|
||||
)
|
||||
from ..logdisplay import OVERVIEW_BANLIST
|
||||
from . import CreateView, PaginationMixin, UpdateView
|
||||
|
||||
@@ -716,20 +719,7 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
|
||||
|
||||
# get all supported placeholders with dummy values
|
||||
def placeholders(self, item):
|
||||
ctx = {}
|
||||
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item]).values():
|
||||
s = str(p.render_sample(self.request.event))
|
||||
if s.strip().startswith('* '):
|
||||
ctx[p.identifier] = '<div class="placeholder" title="{}">{}</div>'.format(
|
||||
_('This value will be replaced based on dynamic parameters.'),
|
||||
markdown_compile_email(s)
|
||||
)
|
||||
else:
|
||||
ctx[p.identifier] = '<span class="placeholder" title="{}">{}</span>'.format(
|
||||
_('This value will be replaced based on dynamic parameters.'),
|
||||
escape(s)
|
||||
)
|
||||
return ctx
|
||||
return get_sample_context(self.request.event, MailSettingsForm.base_context[item])
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
preview_item = request.POST.get('item', '')
|
||||
@@ -751,9 +741,15 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
|
||||
bleach.clean(v), self.placeholders(preview_item), raise_on_missing=True
|
||||
), highlight=True)
|
||||
else:
|
||||
msgs[self.supported_locale[idx]] = markdown_compile_email(
|
||||
format_map(v, self.placeholders(preview_item), raise_on_missing=True)
|
||||
placeholders = self.placeholders(preview_item)
|
||||
msgs[self.supported_locale[idx]] = format_map(
|
||||
markdown_compile_email(
|
||||
format_map(v, placeholders, raise_on_missing=True)
|
||||
),
|
||||
placeholders,
|
||||
mode=SafeFormatter.MODE_RICH_TO_HTML,
|
||||
)
|
||||
|
||||
except ValueError:
|
||||
msgs[self.supported_locale[idx]] = '<div class="alert alert-danger">{}</div>'.format(
|
||||
PlaceholderValidator.error_message)
|
||||
@@ -776,13 +772,18 @@ class MailSettingsRendererPreview(MailSettingsPreview):
|
||||
# get all supported placeholders with dummy values
|
||||
def placeholders(self, item):
|
||||
ctx = {}
|
||||
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item]).values():
|
||||
ctx[p.identifier] = escape(str(p.render_sample(self.request.event)))
|
||||
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item], rich=True).values():
|
||||
sample = p.render_sample(self.request.event)
|
||||
if isinstance(sample, PlainHtmlAlternativeString):
|
||||
ctx[p.identifier] = sample
|
||||
else:
|
||||
ctx[p.identifier] = conditional_escape(sample)
|
||||
return ctx
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
v = str(request.event.settings.mail_text_order_placed)
|
||||
v = format_map(v, self.placeholders('mail_text_order_placed'))
|
||||
context = self.placeholders('mail_text_order_placed')
|
||||
v = format_map(v, context)
|
||||
renderers = request.event.get_html_mail_renderers()
|
||||
if request.GET.get('renderer') in renderers:
|
||||
with rolledback_transaction():
|
||||
@@ -800,7 +801,8 @@ class MailSettingsRendererPreview(MailSettingsPreview):
|
||||
str(request.event.settings.mail_text_signature),
|
||||
gettext('Your order: %(code)s') % {'code': order.code},
|
||||
order,
|
||||
position=None
|
||||
position=None,
|
||||
context=context,
|
||||
)
|
||||
r = HttpResponse(v, content_type='text/html')
|
||||
r._csp_ignore = True
|
||||
|
||||
@@ -134,7 +134,7 @@ from pretix.control.signals import order_search_forms
|
||||
from pretix.control.views import PaginationMixin
|
||||
from pretix.helpers import OF_SELF
|
||||
from pretix.helpers.compat import CompatDeleteView
|
||||
from pretix.helpers.format import format_map
|
||||
from pretix.helpers.format import SafeFormatter, format_map
|
||||
from pretix.helpers.safedownload import check_token
|
||||
from pretix.presale.signals import question_form_fields
|
||||
|
||||
@@ -2351,7 +2351,7 @@ class OrderSendMail(EventPermissionRequiredMixin, OrderViewMixin, FormView):
|
||||
'subject': mark_safe(_('Subject: {subject}').format(
|
||||
subject=prefix_subject(order.event, escape(email_subject), highlight=True)
|
||||
)),
|
||||
'html': markdown_compile_email(email_content)
|
||||
'html': format_map(markdown_compile_email(email_content), email_context, mode=SafeFormatter.MODE_RICH_TO_HTML)
|
||||
}
|
||||
return self.get(self.request, *self.args, **self.kwargs)
|
||||
else:
|
||||
|
||||
@@ -122,7 +122,7 @@ from pretix.control.views.mailsetup import MailSettingsSetupView
|
||||
from pretix.helpers import OF_SELF, GroupConcat
|
||||
from pretix.helpers.compat import CompatDeleteView
|
||||
from pretix.helpers.dicts import merge_dicts
|
||||
from pretix.helpers.format import format_map
|
||||
from pretix.helpers.format import SafeFormatter, format_map
|
||||
from pretix.helpers.urls import build_absolute_uri as build_global_uri
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
from pretix.presale.forms.customer import TokenGenerator
|
||||
@@ -357,9 +357,10 @@ class MailSettingsPreview(OrganizerPermissionRequiredMixin, View):
|
||||
highlight=True,
|
||||
)
|
||||
else:
|
||||
msgs[self.supported_locale[idx]] = markdown_compile_email(
|
||||
format_map(v, self.placeholders(preview_item))
|
||||
)
|
||||
placeholders = self.placeholders(preview_item)
|
||||
msgs[self.supported_locale[idx]] = format_map(markdown_compile_email(
|
||||
format_map(v, placeholders)
|
||||
), placeholders, mode=SafeFormatter.MODE_RICH_TO_HTML)
|
||||
|
||||
return JsonResponse({
|
||||
'item': preview_item,
|
||||
|
||||
@@ -50,7 +50,7 @@ from django.http import (
|
||||
from django.shortcuts import redirect, render
|
||||
from django.urls import resolve, reverse
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.html import escape, format_html
|
||||
from django.utils.html import format_html
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
@@ -59,12 +59,12 @@ from django.views.generic import (
|
||||
)
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
from pretix.base.email import get_available_placeholders
|
||||
from pretix.base.models import (
|
||||
CartPosition, LogEntry, Voucher, WaitingListEntry,
|
||||
)
|
||||
from pretix.base.models.vouchers import generate_codes
|
||||
from pretix.base.services.mail import prefix_subject
|
||||
from pretix.base.services.placeholders import get_sample_context
|
||||
from pretix.base.services.vouchers import vouchers_send
|
||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||
from pretix.base.views.tasks import AsyncFormView
|
||||
@@ -74,7 +74,7 @@ from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.control.signals import voucher_form_class
|
||||
from pretix.control.views import PaginationMixin
|
||||
from pretix.helpers.compat import CompatDeleteView
|
||||
from pretix.helpers.format import format_map
|
||||
from pretix.helpers.format import SafeFormatter, format_map
|
||||
from pretix.helpers.models import modelcopy
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
|
||||
@@ -549,22 +549,10 @@ class VoucherBulkMailPreview(EventPermissionRequiredMixin, View):
|
||||
|
||||
# get all supported placeholders with dummy values
|
||||
def placeholders(self, item):
|
||||
ctx = {}
|
||||
base_ctx = ['event', 'name']
|
||||
if item == 'send_message':
|
||||
base_ctx += ['voucher_list']
|
||||
for p in get_available_placeholders(self.request.event, base_ctx).values():
|
||||
s = str(p.render_sample(self.request.event))
|
||||
if s.strip().startswith('* ') or s.startswith(' '):
|
||||
ctx[p.identifier] = '<div class="placeholder" title="{}">{}</div>'.format(
|
||||
_('This value will be replaced based on dynamic parameters.'),
|
||||
markdown_compile_email(s)
|
||||
)
|
||||
else:
|
||||
ctx[p.identifier] = '<span class="placeholder" title="{}">{}</span>'.format(
|
||||
_('This value will be replaced based on dynamic parameters.'),
|
||||
escape(s)
|
||||
)
|
||||
ctx = get_sample_context(self.request.event, base_ctx)
|
||||
return self.SafeDict(ctx)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
@@ -579,9 +567,10 @@ class VoucherBulkMailPreview(EventPermissionRequiredMixin, View):
|
||||
highlight=True
|
||||
)
|
||||
else:
|
||||
msgs["all"] = markdown_compile_email(
|
||||
format_map(request.POST.get(preview_item), self.placeholders(preview_item))
|
||||
)
|
||||
placeholders = self.placeholders(preview_item)
|
||||
msgs["all"] = format_map(markdown_compile_email(
|
||||
format_map(request.POST.get(preview_item), placeholders)
|
||||
), placeholders, mode=SafeFormatter.MODE_RICH_TO_HTML)
|
||||
|
||||
return JsonResponse({
|
||||
'item': preview_item,
|
||||
|
||||
Reference in New Issue
Block a user