mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
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:
committed by
GitHub
parent
cf9fd47d2b
commit
8c07fa75e4
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
62
src/pretix/base/migrations/0187_normalize_salutation.py
Normal file
62
src/pretix/base/migrations/0187_normalize_salutation.py
Normal 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,
|
||||
),
|
||||
]
|
||||
@@ -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'),
|
||||
|
||||
Reference in New Issue
Block a user