Spec-Zone.ru › Wagtail

Международная локализация

  • Многоязычное содержимое

    • Обзор
    • Подход Wagtail к многоязычному содержимому

      • Структура страницы
      • Как регистрируются языковые версии и переводы в базе данных
      • Переведённые домашние страницы
      • Обнаружение языка и маршрутизация
      • Языковые версии
    • Настройка

      • Включение международной локализации
      • Настройка доступных языков
      • Включение пользовательского интерфейса управления языковыми версиями (необязательно)
      • Добавление префикса языка в URL-адреса
      • Автоматическое определение языка пользователя
      • Настройка маршрутизации/обнаружения языка
    • Рецепты для интернационализированных сайтов

      • Выбор языка/региона
      • Фильтры API для сайтов без фронтенда
      • Переводимые фрагменты
    • Процесс перевода

      • Wagtail Localize
  • Альтернативные плагины международной локализации
  • Переводы административной панели 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.

Обработка языковых регионов, которые используют общее содержимое

Вместо итерации по страницам этот пример итерирует по всем настроенным языкам и находит страницу для каждого из них. Это работает лучше, чем пример Базовый пример выше на сайтах, которые имеют дополнительные Django LANGUAGES которые используют общее содержимое Wagtail.

Для работы этого примера, вам сначала необходимо добавить обработчик контекста Django django.template.context_processors.i18n в настройку TEMPLATES:

# myproject/settings.py

TEMPLATES = [
    {
        # ...
        'OPTIONS': {
            'context_processors': [
                # ...
                'django.template.context_processors.i18n',
            ],
        },
    },
]

Теперь сам пример:

{% for language_code, language_name in LANGUAGES %}
    {% get_language_info for language_code as lang %}

    {% language language_code %}
        <a href="{% pageurl page.localized %}" rel="alternate" hreflang="{{ language_code }}">
            {{ lang.name_local }}
        </a>
    {% endlanguage %}
{% endfor %}

Давайте разберём и это:

{% for language_code, language_name in LANGUAGES %}
    ...
{% endfor %}

Этот for блок итерирует по всем настроенным языкам сайта. Переменная LANGUAGES получена из обработчика контекста django.template.context_processors.i18n.

{% get_language_info for language_code as lang %}

Делает точно то же, что и предыдущий пример.

{% language language_code %}
    ...
{% endlanguage %}

Этот language тег взят из библиотеки тегов Django i18n . Он изменяет активный язык только для кода, заключённого в нём.

<a href="{% pageurl page.localized %}" rel="alternate" hreflang="{{ language_code }}">
    {{ lang.name_local }}
</a>

Единственное отличие тега <a> от тега <a> в предыдущем примере заключается в том, как мы получаем URL страницы: {% pageurl page.localized %}.

Все экземпляры страниц в Wagtail имеют атрибут .localized , который извлекает перевод страницы на текущем активном языке. Вот почему мы активировали язык ранее.

Ещё одно отличие здесь состоит в том, что если одна и та же переведённая страница используется в двух языковых регионах, Wagtail сгенерирует правильный URL страницы, основанный на текущем активном языковом регионе. Это ключевое отличие от предыдущего примера, поскольку предыдущий пример мог получить только URL страницы в её исходном регионовом языке.

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, машинный перевод и внешнюю интеграцию с переводческими службами.

Github: https://github.com/wagtail/wagtail-localize

Альтернативные плагины интернационализации

До того, как в Wagtail была добавлена официальная поддержка нескольких языков, разработчикам сайтов приходилось использовать сторонние плагины. Эти плагины не были заменены собственным реализацией Wagtail, поскольку они используют несколько разные подходы, и один из них может лучше подойти к вашему случаю:

  • Wagtailtrans
  • wagtail-modeltranslation

Сравнение этих вариантов можно найти в статье блога AccordBox How to support multi-language in Wagtail CMS.

Переводы админ-панели Wagtail

Админ-панель Wagtail переведена на многие языки. Список доступных переводов можно найти на странице Transifex Wagtail: https://explore.transifex.com/torchbox/wagtail/. (Обратите внимание: если вы используете старую версию Wagtail, эта страница может не отражать точно доступные языки).

Если ваш язык отсутствует на этой странице, вы можете легко внести вклад в новые языки или исправить ошибки. Зарегистрируйтесь и отправьте изменения на Transifex. Обновления переводов обычно интегрируются в официальный релиз в течение месяца после отправки.

END_OF_DOCUMENT_MARKER

Изменение языка админ-панели 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API