kopia lustrzana https://github.com/wagtail/wagtail
[RFC 54] Internationalisation reference docs (#6377)
* Reference docs for internationalisation * Update docs/reference/pages/model_reference.rst Co-authored-by: Dan Braghis <dan@zerolab.org> * Update docs/reference/pages/model_reference.rst Co-authored-by: Dan Braghis <dan@zerolab.org> * Update docs/reference/pages/model_reference.rst Co-authored-by: Dan Braghis <dan@zerolab.org> * Apply suggestions from code review Co-authored-by: Dan Braghis <dan@zerolab.org> * Add missing comma * Apply suggestions from code review Co-authored-by: Matt Westcott <matthew@torchbox.com> Co-authored-by: Dan Braghis <dan@zerolab.org> Co-authored-by: Matt Westcott <matthew@torchbox.com>pull/6471/head
rodzic
9fab50e87a
commit
0efe4a75a5
|
@ -129,6 +129,22 @@ Database fields
|
|||
|
||||
If set, this page is an alias of the page referenced in this field.
|
||||
|
||||
.. attribute:: locale
|
||||
|
||||
(foreign key to Locale)
|
||||
|
||||
This foreign key links to the ``Locale`` object that represents the page language.
|
||||
|
||||
.. attribute:: translation_key
|
||||
|
||||
(uuid)
|
||||
|
||||
A UUID that is shared between translations of a page. These are randomly generated
|
||||
when a new page is created and copied when a translation of a page is made.
|
||||
|
||||
A translation_key value can only be used on one page in each locale.
|
||||
|
||||
|
||||
Methods and properties
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -184,6 +200,20 @@ In addition to the model fields provided, ``Page`` has many properties and metho
|
|||
|
||||
.. automethod:: get_siblings
|
||||
|
||||
.. automethod:: get_translations
|
||||
|
||||
.. automethod:: get_translation
|
||||
|
||||
.. automethod:: get_translation_or_none
|
||||
|
||||
.. automethod:: has_translation
|
||||
|
||||
.. automethod:: copy_for_translation
|
||||
|
||||
.. autoattribute:: localized
|
||||
|
||||
.. autoattribute:: localized_draft
|
||||
|
||||
.. attribute:: search_fields
|
||||
|
||||
A list of fields to be indexed by the search engine. See Search docs :ref:`wagtailsearch_indexing_fields`
|
||||
|
@ -356,6 +386,87 @@ Methods and properties
|
|||
|
||||
.. automethod:: get_site_root_paths
|
||||
|
||||
|
||||
Locale
|
||||
======
|
||||
|
||||
The ``Locale`` model defines the set of languages and/or locales that can be used on a site.
|
||||
Each ``Locale`` record corresponds to a "language code" defined in the :ref:`wagtail_content_languages_setting` setting.
|
||||
|
||||
Wagtail will initially set up one ``Locale`` to act as the default language for all existing content.
|
||||
This first locale will automatically pick the value from ``WAGTAIL_CONTENT_LANGUAGES`` that most closely matches the site primary language code defined in ``LANGUAGE_CODE``.
|
||||
If the primary language code is changed later, Wagtail will **not** automatically create a new ``Locale`` record or update an existing one.
|
||||
|
||||
Before internationalisation is enabled, all pages use this primary ``Locale`` record.
|
||||
This is to satisfy the database constraints, and makes it easier to switch internationalisation on at a later date.
|
||||
|
||||
Changing ``WAGTAIL_CONTENT_LANGUAGES``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Languages can be added or removed from ``WAGTAIL_CONTENT_LANGUAGES`` over time.
|
||||
|
||||
Before removing an option from ``WAGTAIL_CONTENT_LANGUAGES``, it's important that the ``Locale``
|
||||
record is updated to a use a different content language or is deleted.
|
||||
Any ``Locale`` instances that have invalid content languages are automatically filtered out from all
|
||||
database queries making them unable to be edited or viewed.
|
||||
|
||||
Methods and properties
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. class:: Locale
|
||||
:noindex:
|
||||
|
||||
.. autoattribute:: language_code
|
||||
|
||||
.. automethod:: get_default
|
||||
|
||||
.. automethod:: get_active
|
||||
|
||||
.. automethod:: get_display_name
|
||||
|
||||
|
||||
Translatable Mixin
|
||||
==================
|
||||
|
||||
``TranslatableMixin`` is an abstract model that can be added to any non-page Django model to make it translatable.
|
||||
Pages already include this mixin, so there is no need to add it.
|
||||
|
||||
Methods and properties
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``locale`` and ``translation_key`` fields have a unique key constraint to prevent the object being translated into a language more than once.
|
||||
|
||||
.. class:: TranslatableMixin
|
||||
:noindex:
|
||||
|
||||
.. attribute:: locale
|
||||
|
||||
(Foreign Key to :class:`~wagtail.core.models.Locale`)
|
||||
|
||||
For pages, this defaults to the locale of the parent page.
|
||||
|
||||
.. attribute:: translation_key
|
||||
|
||||
(uuid)
|
||||
|
||||
A UUID that is randomly generated whenever a new model instance is created.
|
||||
This is shared with all translations of that instance so can be used for querying translations.
|
||||
|
||||
.. automethod:: get_translations
|
||||
|
||||
.. automethod:: get_translation
|
||||
|
||||
.. automethod:: get_translation_or_none
|
||||
|
||||
.. automethod:: has_translation
|
||||
|
||||
.. automethod:: copy_for_translation
|
||||
|
||||
.. automethod:: get_translation_model
|
||||
|
||||
.. autoattribute:: localized
|
||||
|
||||
|
||||
.. _page-revision-model-ref:
|
||||
|
||||
``PageRevision``
|
||||
|
|
|
@ -64,6 +64,91 @@ Override the templates used by the search front-end views.
|
|||
|
||||
Set the number of days (default 7) that search query logs are kept for; these are used to identify popular search terms for :ref:`promoted search results <editors-picks>`. Queries older than this will be removed by the :ref:`search_garbage_collect` command.
|
||||
|
||||
Internationalisation
|
||||
====================
|
||||
|
||||
.. versionadded:: 2.11
|
||||
|
||||
Wagtail supports internationalisation of content by maintaining separate trees
|
||||
of pages for each language.
|
||||
|
||||
For a guide on how to enable internationalisation on your site, see the :ref:`configuration guide <enabling_internationalisation>`.
|
||||
|
||||
``WAGTAIL_I18N_ENABLED``
|
||||
------------------------
|
||||
|
||||
(boolean, default ``False``)
|
||||
|
||||
When set to ``True``, Wagtail's internationalisation features will be enabled:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
WAGTAIL_I18N_ENABLED = True
|
||||
|
||||
.. _wagtail_content_languages_setting:
|
||||
|
||||
``WAGTAIL_CONTENT_LANGUAGES``
|
||||
-----------------------------
|
||||
|
||||
(list, default ``[]``)
|
||||
|
||||
A list of languages and/or locales that Wagtail content can be authored in.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
WAGTAIL_CONTENT_LANGUAGES = [
|
||||
('en', _("English")),
|
||||
('fr', _("French")),
|
||||
]
|
||||
|
||||
Each item in the list is a 2-tuple containing a language code and a display name.
|
||||
The language code can either be a language code on its own (such as ``en``, ``fr``),
|
||||
or it can include a region code (such as ``en-gb``, ``fr-fr``).
|
||||
You can mix the two formats if you only need to localize in some regions but not others.
|
||||
|
||||
This setting follows the same structure of Django's ``LANGUAGES`` setting,
|
||||
so they can both be set to the same value:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
LANGUAGES = WAGTAIL_CONTENT_LANGUAGES = [
|
||||
('en-gb', _("English (United Kingdom)")),
|
||||
('en-us', _("English (United States)")),
|
||||
('es-es', _("Spanish (Spain)")),
|
||||
('es-mx', _("Spanish (Mexico)")),
|
||||
]
|
||||
|
||||
However having them separate allows you to configure many different regions on your site
|
||||
yet have them share Wagtail content (but defer on things like date formatting, currency, etc):
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
LANGUAGES = [
|
||||
('en', _("English (United Kingdom)")),
|
||||
('en-us', _("English (United States)")),
|
||||
('es', _("Spanish (Spain)")),
|
||||
('es-mx', _("Spanish (Mexico)")),
|
||||
]
|
||||
|
||||
|
||||
WAGTAIL_CONTENT_LANGUAGES = [
|
||||
('en', _("English")),
|
||||
('es', _("Spanish")),
|
||||
]
|
||||
|
||||
This would mean that your site will respond on the
|
||||
``https://www.mysite.com/es/`` and ``https://www.mysite.com/es-MX/`` URLs, but both
|
||||
of them will serve content from the same "Spanish" tree in Wagtail.
|
||||
|
||||
.. note:: ``WAGTAIL_CONTENT_LANGUAGES`` must be a subset of ``LANGUAGES``
|
||||
|
||||
Note that all languages that exist in ``WAGTAIL_CONTENT_LANGUAGES``
|
||||
must also exist in your ``LANGUAGES`` setting. This is so that Wagtail can
|
||||
generate a live URL to these pages from an untranslated context (e.g. the admin
|
||||
interface).
|
||||
|
||||
Embeds
|
||||
======
|
||||
|
||||
|
|
|
@ -336,6 +336,10 @@ class LocaleManager(models.Manager):
|
|||
|
||||
|
||||
class Locale(models.Model):
|
||||
#: The language code that represents this locale
|
||||
#:
|
||||
#: The language code can either be a language code on its own (such as ``en``, ``fr``),
|
||||
#: or it can include a region code (such as ``en-gb``, ``fr-fr``).
|
||||
language_code = models.CharField(max_length=100, unique=True)
|
||||
|
||||
# Objects excludes any Locales that have been removed from LANGUAGES, This effectively disables them
|
||||
|
@ -406,6 +410,11 @@ class TranslatableMixin(models.Model):
|
|||
|
||||
@property
|
||||
def localized(self):
|
||||
"""
|
||||
Finds the translation in the current active language.
|
||||
|
||||
If there is no translation in the active language, self is returned.
|
||||
"""
|
||||
locale = Locale.get_active()
|
||||
|
||||
if locale.id == self.locale_id:
|
||||
|
@ -414,6 +423,9 @@ class TranslatableMixin(models.Model):
|
|||
return self.get_translation_or_none(locale) or self
|
||||
|
||||
def get_translations(self, inclusive=False):
|
||||
"""
|
||||
Returns a queryset containing the translations of this instance.
|
||||
"""
|
||||
translations = self.__class__.objects.filter(
|
||||
translation_key=self.translation_key
|
||||
)
|
||||
|
@ -424,20 +436,35 @@ class TranslatableMixin(models.Model):
|
|||
return translations
|
||||
|
||||
def get_translation(self, locale):
|
||||
"""
|
||||
Finds the translation in the specified locale.
|
||||
|
||||
If there is no translation in that locale, this raises a ``model.DoesNotExist`` exception.
|
||||
"""
|
||||
return self.get_translations(inclusive=True).get(locale_id=pk(locale))
|
||||
|
||||
def get_translation_or_none(self, locale):
|
||||
"""
|
||||
Finds the translation in the specified locale.
|
||||
|
||||
If there is no translation in that locale, this returns None.
|
||||
"""
|
||||
try:
|
||||
return self.get_translation(locale)
|
||||
except self.__class__.DoesNotExist:
|
||||
return None
|
||||
|
||||
def has_translation(self, locale):
|
||||
"""
|
||||
Returns True if a translation exists in the specified locale.
|
||||
"""
|
||||
return self.get_translations(inclusive=True).filter(locale_id=pk(locale)).exists()
|
||||
|
||||
def copy_for_translation(self, locale):
|
||||
"""
|
||||
Copies this instance for the specified locale.
|
||||
Creates a copy of this instance with the specified locale.
|
||||
|
||||
Note that the copy is initially unsaved.
|
||||
"""
|
||||
translated = self.__class__.objects.get(id=self.id)
|
||||
translated.id = None
|
||||
|
@ -472,15 +499,17 @@ class TranslatableMixin(models.Model):
|
|||
return Locale.get_default()
|
||||
|
||||
@classmethod
|
||||
def get_translation_model(self):
|
||||
def get_translation_model(cls):
|
||||
"""
|
||||
Gets the model which manages the translations for this model.
|
||||
(The model that has the "translation_key" and "locale" fields)
|
||||
Most of the time this would be the current model, but some sites
|
||||
may have intermediate concrete models between wagtailcore.Page and
|
||||
the specfic page model.
|
||||
Returns this model's "Translation model".
|
||||
|
||||
The "Translation model" is the model that has the ``locale`` and
|
||||
``translation_key`` fields.
|
||||
Typically this would be the current model, but it may be a
|
||||
super-class if multi-table inheritance is in use (as is the case
|
||||
for ``wagtailcore.Page``).
|
||||
"""
|
||||
return self._meta.get_field("locale").model
|
||||
return cls._meta.get_field("locale").model
|
||||
|
||||
|
||||
def bootstrap_translatable_model(model, locale):
|
||||
|
@ -1161,6 +1190,14 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
|
|||
|
||||
@property
|
||||
def localized_draft(self):
|
||||
"""
|
||||
Finds the translation in the current active language.
|
||||
|
||||
If there is no translation in the active language, self is returned.
|
||||
|
||||
Note: This will return translations that are in draft. If you want to exclude
|
||||
these, use the ``.localized`` attribute.
|
||||
"""
|
||||
locale = Locale.get_active()
|
||||
|
||||
if locale.id == self.locale_id:
|
||||
|
@ -1170,6 +1207,14 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
|
|||
|
||||
@property
|
||||
def localized(self):
|
||||
"""
|
||||
Finds the translation in the current active language.
|
||||
|
||||
If there is no translation in the active language, self is returned.
|
||||
|
||||
Note: This will not return the translation if it is in draft.
|
||||
If you want to include drafts, use the ``.localized_draft`` attribute instead.
|
||||
"""
|
||||
localized = self.localized_draft
|
||||
if not localized.live:
|
||||
return self
|
||||
|
@ -2205,7 +2250,24 @@ class Page(AbstractPage, index.Indexed, ClusterableModel, metaclass=PageBase):
|
|||
@transaction.atomic
|
||||
def copy_for_translation(self, locale, copy_parents=False, alias=False, exclude_fields=None):
|
||||
"""
|
||||
Copies this page for the specified locale.
|
||||
Creates a copy of this page in the specified locale.
|
||||
|
||||
The new page will be created in draft as a child of this page's translated
|
||||
parent.
|
||||
|
||||
For example, if you are translating a blog post from English into French,
|
||||
this method will look for the French version of the blog index and create
|
||||
the French translation of the blog post under that.
|
||||
|
||||
If this page's parent is not translated into the locale, then a ``ParentNotTranslatedError``
|
||||
is raised. You can circumvent this error by passing ``copy_parents=True`` which
|
||||
copies any parents that are not translated yet.
|
||||
|
||||
The ``exclude_fields`` parameter can be used to set any fields to a blank value
|
||||
in the copy.
|
||||
|
||||
Note that this method calls the ``.copy()`` method internally so any fields that
|
||||
are excluded in ``.exclude_fields_in_copy`` will be excluded from the translation.
|
||||
"""
|
||||
# Find the translated version of the parent page to create the new page under
|
||||
parent = self.get_parent().specific
|
||||
|
|
Ładowanie…
Reference in New Issue