Add salutation "Mx", normalize salutations (save in English, localize on display) (#2075)

* normalize salutations and localize before use

* add migration to normalize salutations

* add placeholder "name_for_salutation" for emails
This commit is contained in:
Richard Schreiber
2021-05-14 09:51:25 +02:00
committed by GitHub
parent cf9fd47d2b
commit 8c07fa75e4
4 changed files with 111 additions and 7 deletions

View File

@@ -32,7 +32,9 @@ from django.db.models import Count
from django.dispatch import receiver
from django.template.loader import get_template
from django.utils.timezone import now
from django.utils.translation import get_language, gettext_lazy as _
from django.utils.translation import (
get_language, gettext_lazy as _, pgettext_lazy,
)
from inlinestyler.utils import inline_css
from pretix.base.i18n import (
@@ -550,16 +552,27 @@ def base_placeholders(sender, **kwargs):
]
name_scheme = PERSON_NAME_SCHEMES[sender.settings.name_scheme]
if "concatenation_for_salutation" in name_scheme:
concatenation_for_salutation = name_scheme["concatenation_for_salutation"]
else:
concatenation_for_salutation = name_scheme["concatenation"]
ph.append(SimpleFunctionalMailTextPlaceholder(
"name_for_salutation", ["position_or_address"],
lambda position_or_address: concatenation_for_salutation(get_best_name(position_or_address, parts=True)),
_("Mr Doe"),
))
for f, l, w in name_scheme['fields']:
if f == 'full_name':
continue
ph.append(SimpleFunctionalMailTextPlaceholder(
'attendee_name_%s' % f, ['position'], lambda position, f=f: position.attendee_name_parts.get(f, ''),
'attendee_name_%s' % f, ['position'], lambda position, f=f: get_name_parts_localized(position.attendee_name_parts, f),
name_scheme['sample'][f]
))
ph.append(SimpleFunctionalMailTextPlaceholder(
'name_%s' % f, ['position_or_address'],
lambda position_or_address, f=f: get_best_name(position_or_address, parts=True).get(f, ''),
lambda position_or_address, f=f: get_name_parts_localized(get_best_name(position_or_address, parts=True), f),
name_scheme['sample'][f]
))
@@ -570,3 +583,10 @@ def base_placeholders(sender, **kwargs):
))
return ph
def get_name_parts_localized(name_parts, key):
value = name_parts.get(key, "")
if key == "salutation":
return pgettext_lazy("person_name_salutation", value)
return value

View File

@@ -119,7 +119,7 @@ class NamePartsWidget(forms.MultiWidget):
if fname == 'title' and self.titles:
widgets.append(Select(attrs=a, choices=[('', '')] + [(d, d) for d in self.titles[1]]))
elif fname == 'salutation':
widgets.append(Select(attrs=a, choices=[('', '---')] + [(s, s) for s in PERSON_NAME_SALUTATIONS]))
widgets.append(Select(attrs=a, choices=[('', '---')] + PERSON_NAME_SALUTATIONS))
else:
widgets.append(self.widget(attrs=a))
super().__init__(widgets, attrs)
@@ -217,7 +217,7 @@ class NamePartsFormField(forms.MultiValueField):
d.pop('max_length', None)
field = forms.ChoiceField(
**d,
choices=[('', '---')] + [(s, s) for s in PERSON_NAME_SALUTATIONS]
choices=[('', '---')] + PERSON_NAME_SALUTATIONS
)
else:
field = forms.CharField(**defaults)

View File

@@ -0,0 +1,62 @@
# Generated by Django 3.2.2 on 2021-05-11 06:55
from django.conf import settings
from django.db import migrations
from django.utils.translation import pgettext
from pretix.base.i18n import language
from pretix.base.settings import PERSON_NAME_SALUTATIONS
def normalize_salutations(apps, schema_editor):
models = (
("pretixbase", "Customer", "name_parts"),
("pretixbase", "InvoiceAddress", "name_parts"),
("pretixbase", "Membership", "attendee_name_parts"),
("pretixbase", "CartPosition", "attendee_name_parts"),
("pretixbase", "OrderPosition", "attendee_name_parts"),
("pretix_exhibitors", "Exhibitor", "contact_name_parts"),
)
for salutation, value in PERSON_NAME_SALUTATIONS:
salutations = []
for lang in settings.LANGUAGES:
with language(lang[0]):
salutation_localized = pgettext("person_name_salutation", salutation)
if (
salutation_localized != salutation
and salutation_localized not in salutations
):
salutations.append(salutation_localized)
for app, model, key in models:
sort_params = {}
sort_params["{}__salutation__in".format(key)] = salutations
try:
m = apps.get_model(app, model)
except LookupError:
continue
try:
qs = m.objects
except AttributeError:
qs = m.all
for o in qs.filter(**sort_params):
val = getattr(o, key)
val["salutation"] = salutation
setattr(o, key, val)
o.save()
class Migration(migrations.Migration):
dependencies = [
("pretixbase", "0186_invoice_sent_to_organizer"),
]
operations = [
migrations.RunPython(
normalize_salutations,
migrations.RunPython.noop,
),
]

View File

@@ -2442,10 +2442,29 @@ PERSON_NAME_TITLE_GROUPS = OrderedDict([
])
PERSON_NAME_SALUTATIONS = [
pgettext_lazy("person_name_salutation", "Ms"),
pgettext_lazy("person_name_salutation", "Mr"),
("Ms", pgettext_lazy("person_name_salutation", "Ms")),
("Mr", pgettext_lazy("person_name_salutation", "Mr")),
("Mx", pgettext_lazy("person_name_salutation", "Mx")),
]
def concatenation_for_salutation(d):
salutation = d.get("salutation")
title = d.get("title")
given_name = d.get("given_name")
family_name = d.get("family_name")
# degree (after name) is not used in salutation
# see https://www.schreibwerkstatt.co.at/2012/12/25/der-umgang-mit-akademischen-graden/
if salutation == "Mx":
salutation = None
elif salutation:
salutation = pgettext("person_name_salutation", salutation)
given_name = None
return " ".join(filter(None, (salutation, title, given_name, family_name)))
PERSON_NAME_SCHEMES = OrderedDict([
('given_family', {
'fields': (
@@ -2613,6 +2632,7 @@ PERSON_NAME_SCHEMES = OrderedDict([
'concatenation': lambda d: ' '.join(
str(p) for p in (d.get(key, '') for key in ["given_name", "family_name"]) if p
),
'concatenation_for_salutation': concatenation_for_salutation,
'sample': {
'salutation': pgettext_lazy('person_name_sample', 'Mr'),
'given_name': pgettext_lazy('person_name_sample', 'John'),
@@ -2630,6 +2650,7 @@ PERSON_NAME_SCHEMES = OrderedDict([
'concatenation': lambda d: ' '.join(
str(p) for p in (d.get(key, '') for key in ["title", "given_name", "family_name"]) if p
),
'concatenation_for_salutation': concatenation_for_salutation,
'sample': {
'salutation': pgettext_lazy('person_name_sample', 'Mr'),
'title': pgettext_lazy('person_name_sample', 'Dr'),
@@ -2653,6 +2674,7 @@ PERSON_NAME_SCHEMES = OrderedDict([
str((', ' if d.get('degree') else '')) +
str(d.get('degree', ''))
),
'concatenation_for_salutation': concatenation_for_salutation,
'sample': {
'salutation': pgettext_lazy('person_name_sample', 'Mr'),
'title': pgettext_lazy('person_name_sample', 'Dr'),