mirror of
https://github.com/pretix/pretix.git
synced 2026-05-09 15:54:03 +00:00
Support for inofficial languages
This commit is contained in:
@@ -24,7 +24,8 @@ Inofficial languages
|
|||||||
guarantee that new or changed features in pretix will be translated in time.
|
guarantee that new or changed features in pretix will be translated in time.
|
||||||
|
|
||||||
Incubating languages
|
Incubating languages
|
||||||
are currently in the process of being translated. They can not yet be selected in pretix by end users.
|
are currently in the process of being translated. They can not yet be selected in pretix by end users on
|
||||||
|
production installations and are only available in development mode for testing.
|
||||||
|
|
||||||
Please contact translate@pretix.eu if you think an incubated language should be promoted to an inofficial one or if
|
Please contact translate@pretix.eu if you think an incubated language should be promoted to an inofficial one or if
|
||||||
you are interested in a partnership to make your language official.
|
you are interested in a partnership to make your language official.
|
||||||
@@ -61,6 +62,12 @@ Going back to the dashboard by clicking on the logo in the top-left corner, you
|
|||||||
of translation projects. You can either filter by projects that already have a translation in your language, or you
|
of translation projects. You can either filter by projects that already have a translation in your language, or you
|
||||||
go to the `pretix project page`_ where you can select specific components.
|
go to the `pretix project page`_ where you can select specific components.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If you want to translate pretix to a new language that is not yet listed here, you are very welcome to do so!
|
||||||
|
While you technically can add the language to the portal yourself, we ask you to drop us a short mail to
|
||||||
|
translate@pretix.eu so we can add it to all components at once and also make it selectabel in pretix itself.
|
||||||
|
|
||||||
.. image:: img/weblate4.png
|
.. image:: img/weblate4.png
|
||||||
:class: screenshot
|
:class: screenshot
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
from pytz import common_timezones
|
from pytz import common_timezones
|
||||||
|
|
||||||
from pretix.base.models import User
|
from pretix.base.models import User
|
||||||
|
from pretix.control.forms import SingleLanguageWidget
|
||||||
|
|
||||||
|
|
||||||
class UserSettingsForm(forms.ModelForm):
|
class UserSettingsForm(forms.ModelForm):
|
||||||
@@ -47,6 +48,9 @@ class UserSettingsForm(forms.ModelForm):
|
|||||||
'timezone',
|
'timezone',
|
||||||
'email'
|
'email'
|
||||||
]
|
]
|
||||||
|
widgets = {
|
||||||
|
'locale': SingleLanguageWidget
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.user = kwargs.pop('user')
|
self.user = kwargs.pop('user')
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
from django.utils.html import conditional_escape
|
from django.utils.html import conditional_escape
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
@@ -102,3 +103,68 @@ class SlugWidget(forms.TextInput):
|
|||||||
ctx = super().get_context(name, value, attrs)
|
ctx = super().get_context(name, value, attrs)
|
||||||
ctx['pre'] = self.prefix
|
ctx['pre'] = self.prefix
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
class MultipleLanguagesWidget(forms.CheckboxSelectMultiple):
|
||||||
|
option_template_name = 'pretixcontrol/multi_languages_widget.html'
|
||||||
|
|
||||||
|
def sort(self):
|
||||||
|
self.choices = sorted(self.choices, key=lambda l: (
|
||||||
|
(
|
||||||
|
0 if l[0] in settings.LANGUAGES_OFFICIAL
|
||||||
|
else (
|
||||||
|
1 if l[0] not in settings.LANGUAGES_INCUBATING
|
||||||
|
else 2
|
||||||
|
)
|
||||||
|
), str(l[1])
|
||||||
|
))
|
||||||
|
|
||||||
|
def options(self, name, value, attrs=None):
|
||||||
|
self.sort()
|
||||||
|
return super().options(name, value, attrs)
|
||||||
|
|
||||||
|
def optgroups(self, name, value, attrs=None):
|
||||||
|
self.sort()
|
||||||
|
return super().optgroups(name, value, attrs)
|
||||||
|
|
||||||
|
def create_option(self, name, value, label, selected, index, subindex=None, attrs=None):
|
||||||
|
opt = super().create_option(name, value, label, selected, index, subindex, attrs)
|
||||||
|
opt['official'] = value in settings.LANGUAGES_OFFICIAL
|
||||||
|
opt['incubating'] = value in settings.LANGUAGES_INCUBATING
|
||||||
|
return opt
|
||||||
|
|
||||||
|
|
||||||
|
class SingleLanguageWidget(forms.Select):
|
||||||
|
|
||||||
|
def modify(self):
|
||||||
|
if hasattr(self, '_modified'):
|
||||||
|
return self.choices
|
||||||
|
self.choices = sorted(self.choices, key=lambda l: (
|
||||||
|
(
|
||||||
|
0 if l[0] in settings.LANGUAGES_OFFICIAL
|
||||||
|
else (
|
||||||
|
1 if l[0] not in settings.LANGUAGES_INCUBATING
|
||||||
|
else 2
|
||||||
|
)
|
||||||
|
), str(l[1])
|
||||||
|
))
|
||||||
|
new_choices = []
|
||||||
|
for k, v in self.choices:
|
||||||
|
new_choices.append((
|
||||||
|
k,
|
||||||
|
v if k in settings.LANGUAGES_OFFICIAL
|
||||||
|
else (
|
||||||
|
'{} (inofficial translation)'.format(v) if k not in settings.LANGUAGES_INCUBATING
|
||||||
|
else '{} (translation in progress)'.format(v)
|
||||||
|
)
|
||||||
|
))
|
||||||
|
self._modified = True
|
||||||
|
self.choices = new_choices
|
||||||
|
|
||||||
|
def options(self, name, value, attrs=None):
|
||||||
|
self.modify()
|
||||||
|
return super().options(name, value, attrs)
|
||||||
|
|
||||||
|
def optgroups(self, name, value, attrs=None):
|
||||||
|
self.modify()
|
||||||
|
return super().optgroups(name, value, attrs)
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ from pretix.base.models import Event, Organizer, TaxRule
|
|||||||
from pretix.base.models.event import EventMetaValue, SubEvent
|
from pretix.base.models.event import EventMetaValue, SubEvent
|
||||||
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
|
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
|
||||||
from pretix.control.forms import (
|
from pretix.control.forms import (
|
||||||
ExtFileField, SlugWidget, SplitDateTimePickerWidget,
|
ExtFileField, MultipleLanguagesWidget, SingleLanguageWidget, SlugWidget,
|
||||||
|
SplitDateTimePickerWidget,
|
||||||
)
|
)
|
||||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||||
from pretix.presale.style import get_fonts
|
from pretix.presale.style import get_fonts
|
||||||
@@ -27,7 +28,7 @@ class EventWizardFoundationForm(forms.Form):
|
|||||||
locales = forms.MultipleChoiceField(
|
locales = forms.MultipleChoiceField(
|
||||||
choices=settings.LANGUAGES,
|
choices=settings.LANGUAGES,
|
||||||
label=_("Use languages"),
|
label=_("Use languages"),
|
||||||
widget=forms.CheckboxSelectMultiple,
|
widget=MultipleLanguagesWidget,
|
||||||
help_text=_('Choose all languages that your event should be available in.')
|
help_text=_('Choose all languages that your event should be available in.')
|
||||||
)
|
)
|
||||||
has_subevents = forms.BooleanField(
|
has_subevents = forms.BooleanField(
|
||||||
@@ -279,11 +280,12 @@ class EventSettingsForm(SettingsForm):
|
|||||||
)
|
)
|
||||||
locales = forms.MultipleChoiceField(
|
locales = forms.MultipleChoiceField(
|
||||||
choices=settings.LANGUAGES,
|
choices=settings.LANGUAGES,
|
||||||
widget=forms.CheckboxSelectMultiple,
|
widget=MultipleLanguagesWidget,
|
||||||
label=_("Available languages"),
|
label=_("Available languages"),
|
||||||
)
|
)
|
||||||
locale = forms.ChoiceField(
|
locale = forms.ChoiceField(
|
||||||
choices=settings.LANGUAGES,
|
choices=settings.LANGUAGES,
|
||||||
|
widget=SingleLanguageWidget,
|
||||||
label=_("Default language"),
|
label=_("Default language"),
|
||||||
)
|
)
|
||||||
show_quota_left = forms.BooleanField(
|
show_quota_left = forms.BooleanField(
|
||||||
@@ -637,6 +639,8 @@ class InvoiceSettingsForm(SettingsForm):
|
|||||||
(r.identifier, r.verbose_name) for r in event.get_invoice_renderers().values()
|
(r.identifier, r.verbose_name) for r in event.get_invoice_renderers().values()
|
||||||
]
|
]
|
||||||
self.fields['invoice_numbers_prefix'].widget.attrs['placeholder'] = event.slug.upper() + '-'
|
self.fields['invoice_numbers_prefix'].widget.attrs['placeholder'] = event.slug.upper() + '-'
|
||||||
|
locale_names = dict(settings.LANGUAGES)
|
||||||
|
self.fields['invoice_language'].choices = [('__user__', _('The user\'s language'))] + [(a, locale_names[a]) for a in event.settings.locales]
|
||||||
|
|
||||||
|
|
||||||
class MailSettingsForm(SettingsForm):
|
class MailSettingsForm(SettingsForm):
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from i18nfield.forms import I18nFormField, I18nTextarea
|
|||||||
|
|
||||||
from pretix.base.forms import I18nModelForm, SettingsForm
|
from pretix.base.forms import I18nModelForm, SettingsForm
|
||||||
from pretix.base.models import Organizer, Team
|
from pretix.base.models import Organizer, Team
|
||||||
from pretix.control.forms import ExtFileField
|
from pretix.control.forms import ExtFileField, MultipleLanguagesWidget
|
||||||
from pretix.multidomain.models import KnownDomain
|
from pretix.multidomain.models import KnownDomain
|
||||||
from pretix.presale.style import get_fonts
|
from pretix.presale.style import get_fonts
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ class OrganizerDisplaySettingsForm(SettingsForm):
|
|||||||
locales = forms.MultipleChoiceField(
|
locales = forms.MultipleChoiceField(
|
||||||
choices=settings.LANGUAGES,
|
choices=settings.LANGUAGES,
|
||||||
label=_("Use languages"),
|
label=_("Use languages"),
|
||||||
widget=forms.CheckboxSelectMultiple,
|
widget=MultipleLanguagesWidget,
|
||||||
help_text=_('Choose all languages that your organizer homepage should be available in.')
|
help_text=_('Choose all languages that your organizer homepage should be available in.')
|
||||||
)
|
)
|
||||||
primary_font = forms.ChoiceField(
|
primary_font = forms.ChoiceField(
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
{% if wrap_label %}
|
||||||
|
<label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %}>
|
||||||
|
{% endif %}
|
||||||
|
{% include "django/forms/widgets/input.html" %}
|
||||||
|
{% if wrap_label %}
|
||||||
|
{{ widget.label }}
|
||||||
|
{% if widget.incubating %}
|
||||||
|
<span class="label label-danger" data-toggle="tooltip" title="{% trans "The translation for this language is still in progress. This language can currently only be selected on development installations of pretix, not in production." %}">
|
||||||
|
{% trans "Translation in development" %}
|
||||||
|
</span>
|
||||||
|
{% elif not widget.official %}
|
||||||
|
<span class="label label-warning" data-toggle="tooltip" title="{% trans "This translation is not maintained by the pretix team. We cannot vouch for its correctness and new or recently changed features might not be translated and will show in English instead. You can help translating at translate.pretix.eu." %}">
|
||||||
|
{% trans "Inofficial translation" %}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
6
src/pretix/plugins/stripe/utils.py
Normal file
6
src/pretix/plugins/stripe/utils.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
def refresh_order(order):
|
||||||
|
if not order.payment_provider.startswith('stripe_'):
|
||||||
|
raise ValueError("Not a stripe payment")
|
||||||
|
|
||||||
|
prov = order.event.get_payment_providers()[order.payment_provider]
|
||||||
|
prov._init_api()
|
||||||
@@ -343,11 +343,26 @@ FORMAT_MODULE_PATH = [
|
|||||||
'pretix.helpers.formats',
|
'pretix.helpers.formats',
|
||||||
]
|
]
|
||||||
|
|
||||||
LANGUAGES = [
|
ALL_LANGUAGES = [
|
||||||
('en', _('English')),
|
('en', _('English')),
|
||||||
('de', _('German')),
|
('de', _('German')),
|
||||||
('de-informal', _('German (informal)')),
|
('de-informal', _('German (informal)')),
|
||||||
|
('nl', _('Dutch')),
|
||||||
|
('da', _('Danish')),
|
||||||
|
('pt-br', _('Portuguese (Brazil)')),
|
||||||
]
|
]
|
||||||
|
LANGUAGES_OFFICIAL = {
|
||||||
|
'en', 'de', 'de-informal'
|
||||||
|
}
|
||||||
|
LANGUAGES_INCUBATING = {
|
||||||
|
'nl', 'pt-br', 'da'
|
||||||
|
}
|
||||||
|
|
||||||
|
if DEBUG:
|
||||||
|
LANGUAGES = ALL_LANGUAGES
|
||||||
|
else:
|
||||||
|
LANGUAGES = [(k, v) for k, v in ALL_LANGUAGES if k not in LANGUAGES_INCUBATING]
|
||||||
|
|
||||||
|
|
||||||
EXTRA_LANG_INFO = {
|
EXTRA_LANG_INFO = {
|
||||||
'de-informal': {
|
'de-informal': {
|
||||||
|
|||||||
Reference in New Issue
Block a user