Подтвердить что ты не робот

Определить язык пользователя в Pyramid

Я хочу сделать интернационализацию для своего проекта. Я последовал за тем, как это описано в официальной документации, но локализация все еще не работает. Вот как я пытаюсь получить пользовательский язык:

def get_locale_name(request):
    """ Return the :term:`locale name` associated with the current
    request (possibly cached)."""
    locale_name = getattr(request, 'locale_name', None)
    if locale_name is None:
       locale_name = negotiate_locale_name(request)
       request.locale_name = locale_name
   return locale_name

Но request не имеет attr "local_name", но имеет "Accept-Language", поэтому, когда функция get_local_name не находит "local_name" в запросе, она вызывает другую функцию:

def negotiate_locale_name(request):
    """ Negotiate and return the :term:`locale name` associated with
    the current request (never cached)."""
    try:
        registry = request.registry
    except AttributeError:
        registry = get_current_registry()
    negotiator = registry.queryUtility(ILocaleNegotiator,
                                       default=default_locale_negotiator)
    locale_name = negotiator(request)

   if locale_name is None:
        settings = registry.settings or {}
        locale_name = settings.get('default_locale_name', 'en')

   return locale_name

Как я могу видеть, что negotiator пытается получить локальное из глобальной среды, но если он не может сделать это, его установочное значение из config. И я не могу понять, почему Pyramid не получает локаль непосредственно из поля запроса "Accept-Language"?

И как я могу правильно определить локаль?

4b9b3361

Ответ 1

Пирамида не диктует, как следует согласовывать язык. Основание вашего языка сайта в заголовке "Accept-Language" может вызвать проблемы, так как большинство пользователей не знают, как устанавливать предпочтительные языки браузера. Удостоверьтесь, что ваши пользователи могут легко переключаться между языками и использовать cookie для сохранения предпочтений для будущих посещений.

Вам нужно либо установить _LOCALE_ в запросе (например, с помощью обработчика событий), либо предоставить свой собственный пользовательский переговорный язык.

Здесь приведен пример использования NewRequest событие и accept_language, который является экземпляром webob Accept class:

from pyramid.events import NewRequest
from pyramid.events import subscriber

@subscriber(NewRequest)
def setAcceptedLanguagesLocale(event):
    if not event.request.accept_language:
        return
    accepted = event.request.accept_language
    event.request._LOCALE_ = accepted.best_match(('en', 'fr', 'de'), 'en')

Ответ 2

Обратите внимание, что request._LOCALE_ работает только потому, что по умолчанию переговорщик locale является default_locale_negotiator. Если у вас очень сложные проверки, например, вы должны получить пользователя из БД, если файл cookie не существует, обработчик NewRequest имеет накладные расходы для запросов, которые не нуждаются в каких-либо переводах. Для них вы также можете использовать пользовательский переговорщик locale, например:

def my_locale_negotiator(request):
    if not hasattr(request, '_LOCALE_'):
        request._LOCALE_ = request.accept_language.best_match(
            ('en', 'fr', 'de'), 'en')

    return request._LOCALE_


from pyramid.config import Configurator
config = Configurator()
config.set_locale_negotiator(my_locale_negotiator)

Ответ 3

Как и в случае с пирамидой 1.5, вы можете использовать эти свойства запроса для доступа к текущему языку:

request.localizer экземпляр Localizer

request.locale так же, как request.localizer.locale_name