mirror of
https://github.com/pretix/pretix.git
synced 2025-12-21 16:42:26 +00:00
72 lines
3.4 KiB
ReStructuredText
72 lines
3.4 KiB
ReStructuredText
Internationalization
|
|
====================
|
|
|
|
One of pretix's major selling points is its multi-language capability. We make heavy use of Django's
|
|
`translation features`_ that are built upon `GNU gettext`_. However, Django does not provide a standard
|
|
way to translate *user-generated content*. In our case, we need to translate strings like product names
|
|
or event descriptions, so we need event organizers to be able to fill in all fields in multiple languages.
|
|
|
|
.. note:: Implementing object-level translation in a relational database is a task that requires some difficult
|
|
trade-off. We decided for a design that is not elegant on the database level (as it violates the `1NF`_) and
|
|
makes searching in the respective database fields very hard, but allows for a simple design on the ORM level
|
|
and adds only minimal performance overhead.
|
|
|
|
All classes and functions introduced in this document are located in ``pretix.base.i18n`` if not stated otherwise.
|
|
|
|
Database storage
|
|
----------------
|
|
|
|
pretix provides two custom model field types that allow you to work with localized strings: ``I18nCharField`` and
|
|
``I18nTextField``. Both of them are stored in the database as a ``TextField`` internally, they only differ in the
|
|
default form widget that is used by ``ModelForm``.
|
|
|
|
As pretix does not use these fields in places that need to be searched, the negative performance impact when searching
|
|
and indexing these fields in negligible, as mentioned above. Lookups are currently not even implemented on these
|
|
fields. In the database, the strings will be stored as a JSON-encoded mapping of language codes to strings.
|
|
|
|
Whenever you interact with those fields, you will either provide or receive an instance of the following class:
|
|
|
|
.. autoclass:: pretix.base.i18n.LazyI18nString
|
|
:members: __init__, localize, __str__
|
|
|
|
|
|
Forms
|
|
-----
|
|
|
|
We provide i18n-aware versions of the respective form fields and widgets: ``I18nFormField`` with the ``I18nTextInput``
|
|
and ``I18nTextarea`` widgets. They transparently allow you to use ``LazyI18nString`` values in forms and render text
|
|
inputs for multiple languages.
|
|
|
|
.. autoclass:: pretix.base.i18n.I18nFormField
|
|
|
|
To easily limit the displayed languages to the languages relevant to an event, there is a custom ``ModelForm`` subclass
|
|
that deals with this for you:
|
|
|
|
.. autoclass:: pretix.base.forms.I18nModelForm
|
|
|
|
There are equivalents for ``BaseModelFormSet`` and ``BaseInlineFormSet``:
|
|
|
|
.. autoclass:: pretix.base.forms.I18nFormSet
|
|
|
|
.. autoclass:: pretix.base.forms.I18nInlineFormSet
|
|
|
|
Useful utilities
|
|
----------------
|
|
|
|
The ``i18n`` module contains a few more useful utilities, starting with simple lazy-evaluation wrappers for formatted
|
|
numbers and dates, ``LazyDate`` and ``LazyNumber``. There also is a ``LazyLocaleException`` base class that provides
|
|
exceptions with gettext-localized exception messages.
|
|
|
|
Last, but definitely not least, we have the ``language`` context manager (``pretix.base.i18n.language``) that allows
|
|
you to execute a piece of code with a different locale::
|
|
|
|
with language('de'):
|
|
render_mail_template()
|
|
|
|
This is very useful e.g. when sending an email to a user that has a different language than the user performing the
|
|
action that causes the mail to be sent.
|
|
|
|
.. _translation features: https://docs.djangoproject.com/en/1.9/topics/i18n/translation/
|
|
.. _GNU gettext: https://www.gnu.org/software/gettext/
|
|
.. _1NF: https://en.wikipedia.org/wiki/First_normal_form
|