Международная локализация
- Альтернативные плагины международной локализации
- Переводы административной панели Wagtail
- Изменение языка административной панели Wagtail для каждого пользователя
- Изменение основного языка вашей установки Wagtail
Многоязычное содержимое
Обзор
По умолчанию Wagtail предполагает, что всё содержимое будет написано на одном языке. Этот документ описывает, как настроить Wagtail для создания содержимого на нескольких языках.
Примечание
Wagtail предоставляет инфраструктуру для создания и отображения содержимого на нескольких языках. Существует два варианта управления переводами разных языков в интерфейсе администратора: wagtail.contrib.simple_translation или более продвинутый wagtail-localize (плагин стороннего разработчика).
Этот документ охватывает только интернационализацию содержимого, управляемого Wagtail. Для получения информации о переводе статического содержимого в файлах шаблонов, коде JavaScript и т. п., обратитесь к документации Django по международной локализации https://docs.djangoproject.com/en/3.1/topics/i18n/translation/. Или, если вы создаёте сайт без фронтенда, обратитесь к документации используемого вами фреймворка для фронтенда.
Подход Wagtail к многоязычному содержимому
Этот раздел объясняет подход Wagtail к интернационализации. Если вы спешите, можете перейти к Настройке.
Вкратце:
- Wagtail хранит содержимое в отдельном дереве страниц для каждой языковой версии
- Он имеет встроенную
Localeмодель, и все страницы связаны сLocaleс помощью поля внешнего ключаlocale - Он регистрирует, какие страницы являются переводами друг друга, используя общий UUID, хранящийся в поле
translation_key - Он автоматически маршрутизирует запросы через переводы домашней страницы сайта
- Он использует утилиты Django
i18n_patternsиLocaleMiddlewareдля определения языка
Структура страницы
Wagtail хранит содержимое в отдельном дереве страниц для каждой языковой версии.
Например, если у вас два сайта на двух языковых версиях, то вы увидите четыре домашние страницы на верхнем уровне иерархии страниц в обозревателе.
Этот подход имеет некоторые преимущества для работы редактора:
- Нет языка по умолчанию для редактирования, поэтому содержимое может быть написано на любом языке, а затем переведено на любой другой.
- Переводы страницы — это отдельные страницы, поэтому их можно публиковать в разное время.
- Редакторам можно предоставить разрешение на редактирование содержимого на одной языковой версии и не на других.
Как регистрируются языковые версии и переводы в базе данных
У всех страниц (и любых фрагментов, для которых включён перевод) есть поля locale и translation_key:
-
locale— внешний ключ к моделиLocale -
translation_key— UUID, используемый для поиска переводов фрагмента содержимого. Переводы одной и той же страницы/фрагмента имеют одинаковое значение в этом поле.
Эти два поля имеют ограничение «уникальное вместе», поэтому у вас не может быть более одного перевода на одном языке.
Переведённые домашние страницы
При настройке сайта в Wagtail вы выбираете домашнюю страницу сайта в поле «Главная страница» и все запросы к корневому URL-адресу сайта будут перенаправлены на эту страницу.
На многоязычных сайтах есть отдельная домашняя страница для каждой языковой версии, которая существует как братская страница в дереве страниц. Wagtail находит другие домашние страницы, ища переводы главной страницы сайта.
Это означает, что чтобы сайт стал доступным на другом языке, вам нужно просто перевести и опубликовать его домашнюю страницу на этом языке.
Если Wagtail не может найти домашнюю страницу, соответствующую языку пользователя, он вернётся к странице, выбранной как «Главная страница» на записи сайта, поэтому вы можете использовать это поле для указания языка по умолчанию вашего сайта.
Обнаружение языка и маршрутизация
Для определения языка пользователя и добавления префикса к URL-адресам (например, /en/, /fr-fr/) Wagtail разработан для работы с встроенными утилитами интернационализации Django, такими как i18n_patterns и LocaleMiddleware. Это означает, что Wagtail должен беспрепятственно работать с другими интернационализированными приложениями Django на вашем сайте.
Языковые версии
Языковые версии, включенные на сайте, записываются в модели Locale в wagtailcore. Эта модель содержит всего два поля: ID и language_code, хранящий тег языка BCP-47, представляющий эту языковую версию.
Записи языковых версий можно настроить с помощью необязательного пользовательского интерфейса управления или создать в командной строке. Возможные значения поля language_code контролируются настройкой WAGTAIL_CONTENT_LANGUAGES
Примечание
Прочтите это, если вы изменили LANGUAGE_CODE до включения международной локализации
При первой миграции Wagtail создаёт запись Locale для языка, установленного в настройке LANGUAGE_CODE в момент выполнения миграции. Все страницы будут назначены этой Locale при отключении международной локализации Wagtail.
Если вы изменили LANGUAGE_CODE с момента обновления до Wagtail 2.11, вам нужно будет вручную обновить запись в модели Locale перед включением международной локализации, так как ваше существующее содержимое будет назначено старому коду.
Настройка
В этом разделе мы рассмотрим минимальную конфигурацию, необходимую для включения возможности создания контента на нескольких языках.
- Включение интернационализации
- Настройка доступных языков
- Включение пользовательского интерфейса управления локалями (необязательно)
- Добавление префикса языка в URL-адреса
- Автоопределение языка пользователя
- Настройка маршрутизации/определения языка
Включение интернационализации
Для включения интернационализации как в Django, так и в Wagtail, установите следующие настройки на True.
# my_project/settings.py USE_I18N = True WAGTAIL_I18N_ENABLED = True
Кроме того, возможно, вы захотите включить поддержку локализации Django. Это позволит отображать даты и числа в формате, соответствующем локали пользователя:
# my_project/settings.py USE_L10N = True
Настройка доступных языков
Далее нам нужно настроить доступные языки. Для этого есть две настройки, каждая из которых используется для разных целей:
-
LANGUAGES- это настройка, определяющая, какие языки будут доступны на переднем плане сайта. -
WAGTAIL_CONTENT_LANGUAGES- это настройка, определяющая, на каких языках можно создавать контент Wagtail.
Вы можете установить обе эти настройки в точное одинаковое значение. Например, чтобы включить английский, французский и испанский языки:
# my_project/settings.py
WAGTAIL_CONTENT_LANGUAGES = LANGUAGES = [
('en', "English"),
('fr', "French"),
('es', "Spanish"),
]
Примечание
Всякий раз, когда WAGTAIL_CONTENT_LANGUAGES изменяется, модель Locale также должна быть обновлена в соответствии с этим.
Это можно сделать с помощью миграции данных или с помощью опционального пользовательского интерфейса управления локалями, описанного в следующем разделе.
Вы также можете установить эти значения в разные значения. Возможно, вы захотите сделать это, если хотите иметь некоторую программную локализация (например, форматирование дат или валют), но использовать тот же контент Wagtail в нескольких регионах:
# my_project/settings.py
LANGUAGES = [
('en-GB', "English (Great Britain)"),
('en-US', "English (United States)"),
('en-CA', "English (Canada)"),
('fr-FR', "French (France)"),
('fr-CA', "French (Canada)"),
]
WAGTAIL_CONTENT_LANGUAGES = [
('en-GB', "English"),
('fr-FR', "French"),
]
При такой настройке сайт будет доступен на всех разных локалях в первом списке, но в Wagtail будет только две структуры языков.
Все en- локали будут использовать языковую структуру «Английский», а fr- локали — языковую структуру «Французский». Различия между каждой локалью в языке будут программными. Например: какой формат даты/числа использовать и какую валюту отображать в ценах.
Включение пользовательского интерфейса управления локалями (необязательно)
Доступно приложение для управления локалями, позволяющее администратору Wagtail настраивать локали через интерфейс Wagtail.
Для его включения добавьте wagtail.locales в INSTALLED_APPS.
# my_project/settings.py
INSTALLED_APPS = [
# ...
'wagtail.locales',
# ...
]
Добавление префикса языка в URL-адреса
Для того чтобы все деревья страниц были доступны на одном домене, нам нужно добавить префикс URL-адреса для каждого языка.
Для этого мы можем использовать встроенную функцию Django i18n_patterns, которая добавляет префикс языка ко всем URL-образцам, переданным в неё. Это активирует код языка, указанный в URL, и Wagtail учитывает это при принятии решения о том, как обработать запрос.
В файле urls.py вашего проекта добавьте основные URL-адреса Wagtail (и любые другие URL-адреса, которые вы хотите перевести) в блок i18n_patterns.
# /my_project/urls.py
# ...
from django.conf.urls.i18n import i18n_patterns
# Non-translatable URLs
# Note: if you are using the Wagtail API or sitemaps,
# these should not be added to `i18n_patterns` either
urlpatterns = [
path('django-admin/', admin.site.urls),
path('admin/', include(wagtailadmin_urls)),
path('documents/', include(wagtaildocs_urls)),
]
# Translatable URLs
# These will be available under a language code prefix. For example /en/search/
urlpatterns += i18n_patterns(
path('search/', search_views.search, name='search'),
path("", include(wagtail_urls)),
)
Пропуск префикса языка для языка по умолчанию
Если вы хотите, чтобы URL-адреса вашего языка по умолчанию разрешались без префикса языка, вы можете установить параметр prefix_default_language в i18n_patterns на значение False. Например, если ваши языки настроены следующим образом:
# myproject/settings.py
# ...
LANGUAGE_CODE = 'en'
WAGTAIL_CONTENT_LANGUAGES = LANGUAGES = [
('en', "English"),
('fr', "French"),
]
# ...
И ваш urls.py настроен следующим образом:
# myproject/urls.py
# ...
# These URLs will be available under a language code prefix only for languages that
# are not set as default in LANGUAGE_CODE.
urlpatterns += i18n_patterns(
path('search/', search_views.search, name='search'),
path("", include(wagtail_urls)),
prefix_default_language=False,
)
Теперь ваши URL-адреса будут иметь префикс только для французской версии вашего сайта, например:
- /search/ - /fr/search/
Автоопределение языка пользователя
После обертывания ваших URL-образцов с i18n_patterns, ваш сайт теперь будет реагировать на URL-префиксы. Но сейчас он не будет реагировать на корневой путь.
Для решения этой проблемы нам нужно определить язык браузера пользователя и перенаправить его на лучший префикс языка. Рекомендуемый подход — использовать LocaleMiddleware Django:
# my_project/settings.py
MIDDLEWARE = [
# ...
'django.middleware.locale.LocaleMiddleware',
# ...
]
Настройка маршрутизации/определения языка
Вам не обязательно использовать i18n_patterns или LocaleMiddleware для этого, и вы можете написать свою собственную логику, если это необходимо.
Wagtail требуется только, чтобы язык был активирован (с помощью функции Django django.utils.translation.activate) перед вызовом представления wagtail.views.serve.
Рецепты для интернационализированных сайтов
Выбор языка/региона
Возможно, самый важный элемент пользовательского интерфейса, связанный с интернационализацией, который вы можете добавить на свой сайт, — это селектор, позволяющий пользователям переключаться между различными языками.
Если вы не уверены, что вам это нужно, ознакомьтесь со статьёй https://www.w3.org/International/questions/qa-site-conneg#yyyshortcomings для обоснования.
Базовый пример
Вот базовый пример того, как добавить ссылки между переводами страницы.
Однако в этом примере будут включены только языки, определённые в WAGTAIL_CONTENT_LANGUAGES, а не любые дополнительные языки, которые могут быть определены в LANGUAGES. Для получения дополнительной информации о значении этих настроек см. Настройка доступных языков.
Если оба параметра настроены на одинаковое значение, этот пример должен хорошо работать для вас; в противном случае перейдите к следующему разделу с более сложным примером, который учитывает это.
{# make sure these are at the top of the file #}
{% load i18n wagtailcore_tags %}
{% if page %}
{% for translation in page.get_translations.live %}
{% get_language_info for translation.locale.language_code as lang %}
<a href="{% pageurl translation %}" rel="alternate" hreflang="{{ language_code }}">
{{ lang.name_local }}
</a>
{% endfor %}
{% endif %}
Давайте разберём это:
{% if page %}
...
{% endif %}
Если это часть общей базовой темы, она может использоваться в ситуациях, когда объект страницы недоступен, таких как ответы на ошибки 404, поэтому проверьте, есть ли у нас страница, прежде чем продолжать.
{% for translation in page.get_translations.live %}
...
{% endfor %}
Этот for блок итерирует по всем опубликованным переводам текущей страницы.
{% get_language_info for translation.locale.language_code as lang %}
Это встроенный тег Django, который получает информацию о языке перевода. Для получения дополнительной информации см. get_language_info() в документации Django.
<a href="{% pageurl translation %}" rel="alternate" hreflang="{{ language_code }}">
{{ lang.name_local }}
</a>
Это добавляет ссылку на перевод. Мы используем {{ lang.name_local }} для отображения названия региона в его собственном языке. Мы также добавляем атрибуты rel и hreflang к тегу <a> для SEO.
API-фильтры для сайтов без головной части
Для сайтов без головной части API Wagtail поддерживает два дополнительных фильтра для интернационализированных сайтов:
-
?locale=Фильтрует страницы по заданному языковому региону -
?translation_of=Фильтрует страницы, чтобы включить только переводы данной страницы с заданным идентификатором
Для получения дополнительной информации см. Специальные фильтры для интернационализированных сайтов.
Переводимые фрагменты
Вы можете сделать фрагмент переводимым, сделав его наследником wagtail.models.TranslatableMixin. Например:
# myapp/models.py
from django.db import models
from wagtail.models import TranslatableMixin
from wagtail.snippets.models import register_snippet
@register_snippet
class Advert(TranslatableMixin, models.Model):
name = models.CharField(max_length=255)
Модель TranslatableMixin добавляет поля locale и translation_key в модель.
Преобразование фрагментов с существующими данными в переводимые
Для фрагментов с существующими данными невозможно просто добавить TranslatableMixin, создать миграцию и запустить её. Это связано с тем, что поля locale и translation_key являются обязательными, и translation_key требует уникального значения для каждого экземпляра.
Чтобы правильно мигрировать существующие данные, нам сначала нужно использовать BootstrapTranslatableMixin, которое исключает эти ограничения, затем добавить миграцию данных для установки двух полей, а затем переключиться на TranslatableMixin.
Это необходимо только в том случае, если в базе данных есть записи. Поэтому, если модель пуста, вы можете сразу добавить TranslatableMixin и пропустить это.
Шаг 1: Добавление BootstrapTranslatableMixin в модель
Это добавит два поля без каких-либо ограничений:
# myapp/models.py
from django.db import models
from wagtail.models import BootstrapTranslatableMixin
from wagtail.snippets.models import register_snippet
@register_snippet
class Advert(BootstrapTranslatableMixin, models.Model):
name = models.CharField(max_length=255)
# if the model has a Meta class, ensure it inherits from
# BootstrapTranslatableMixin.Meta too
class Meta(BootstrapTranslatableMixin.Meta):
verbose_name = 'adverts'
Запустите python manage.py makemigrations myapp для создания миграции схемы.
Шаг 2: Создание миграции данных
Создайте миграцию данных с помощью следующей команды:
python manage.py makemigrations myapp --empty
Это создаст новую пустую миграцию в папке migrations приложения. Отредактируйте эту миграцию и добавьте BootstrapTranslatableModel для каждой модели, чтобы выполнить инициализацию в этом приложении:
from django.db import migrations
from wagtail.models import BootstrapTranslatableModel
class Migration(migrations.Migration):
dependencies = [
('myapp', '0002_bootstraptranslations'),
]
# Add one operation for each model to bootstrap here
# Note: Only include models that are in the same app!
operations = [
BootstrapTranslatableModel('myapp.Advert'),
]
Повторите это для любых других приложений, содержащих модель, которую нужно инициализировать.
Шаг 3: Изменение BootstrapTranslatableMixin на TranslatableMixin
Теперь, когда у нас есть миграция, которая заполняет необходимые поля, мы можем заменить BootstrapTranslatableMixin на TranslatableMixin , которая имеет все ограничения:
# myapp/models.py
from wagtail.models import TranslatableMixin # Change this line
@register_snippet
class Advert(TranslatableMixin, models.Model): # Change this line
name = models.CharField(max_length=255)
class Meta(TranslatableMixin.Meta): # Change this line, if present
verbose_name = 'adverts'
Шаг 4: Запуск makemigrations для создания миграций схемы, а затем миграции!
Запустите makemigrations для создания миграции схемы, добавляющей ограничения в базу данных, а затем запустите migrate для выполнения всех миграций:
python manage.py makemigrations myapp python manage.py migrate
При запросе выбора исправления для поля `locale`, которое становится обязательным, выберите вариант «Игнорировать пока» (поскольку это было обработано миграцией данных).
Процесс перевода
Как уже упоминалось в начале, Wagtail предоставляет wagtail.contrib.simple_translation.
Модуль `simple_translation` предоставляет пользовательский интерфейс, который позволяет пользователям копировать страницы и переводимые фрагменты на другой язык.
- Копии создаются на исходном языке (не переведены)
- Копии страниц находятся в статусе черновика
Редакторам контента необходимо перевести содержимое и опубликовать страницы.
Для активации добавьте "wagtail.contrib.simple_translation" в INSTALLED_APPS и запустите python manage.py migrate для создания разрешений submit_translation. В админке Wagtail перейдите в настройки и предоставьте некоторым пользователям или группам разрешение «Может отправлять переводы».
Примечание
Модуль `Simple Translation` является необязательным. Его можно заменить сторонними пакетами. Например, более продвинутым пакетом wagtail-localize.
Wagtail Localize
В рамках начальной работы по внедрению интернационализации в ядро Wagtail мы также создали пакет переводов под названием wagtail-localize. Он поддерживает перевод страниц в Wagtail, используя файлы PO, машинный перевод и внешнюю интеграцию с переводческими службами.
Альтернативные плагины интернационализации
До того, как в Wagtail была добавлена официальная поддержка нескольких языков, разработчикам сайтов приходилось использовать сторонние плагины. Эти плагины не были заменены собственным реализацией Wagtail, поскольку они используют несколько разные подходы, и один из них может лучше подойти к вашему случаю:
Сравнение этих вариантов можно найти в статье блога AccordBox How to support multi-language in Wagtail CMS.
Переводы админ-панели Wagtail
Админ-панель Wagtail переведена на многие языки. Список доступных переводов можно найти на странице Transifex Wagtail: https://explore.transifex.com/torchbox/wagtail/. (Обратите внимание: если вы используете старую версию Wagtail, эта страница может не отражать точно доступные языки).
Если ваш язык отсутствует на этой странице, вы можете легко внести вклад в новые языки или исправить ошибки. Зарегистрируйтесь и отправьте изменения на Transifex. Обновления переводов обычно интегрируются в официальный релиз в течение месяца после отправки.
Изменение языка админ-панели Wagtail для каждого пользователя
Авторизованные пользователи могут установить свой предпочтительный язык в /admin/account/. По умолчанию Wagtail предоставляет список языков, имеющих охват перевода >= 90%. Этот список можно переопределить, используя параметр WAGTAILADMIN_PERMITTED_LANGUAGES.
В случае, если разрешено ноль или один язык, форма будет скрыта.
Если пользователь не выбрал язык, будет использован LANGUAGE_CODE.
Изменение основного языка вашей установки Wagtail
По умолчанию язык Wagtail — en-us (американский английский). Вы можете изменить его, внеся несколько изменений в настройки Django:
- Убедитесь, что USE_I18N установлено в
True. - Установите LANGUAGE_CODE на основной язык вашего сайта.
Если для вашего языка доступен перевод, админ-панель Wagtail должна теперь отображаться на выбранном вами языке.
© 2014-present Torchbox Ltd and individual contributors.
All rights are reserved.
Licensed under the BSD License.
https://docs.wagtail.org/en/stable/advanced_topics/i18n.html