Я бы хотел воспользоваться преимуществами новых возможностей webapp2 для локализации, которые также имеют форматирование времени и валюты, зависящее от локали.
В Django есть хорошая функция get_language_from_request которые я использовал до того, как полностью перешел на webapp2, и теперь я использую i18n из webapp2, и я могу переключаться между локализациями, которые я пишу с помощью gettext, и компилировать в файлы с именем messages.mo, которые мое приложение может читать и отображать. затем определили и расставили приоритеты для следующих способов определения языка пользователя:
1. HTTP GET, например. hl = pt-br для бразильского португальского
2. Переменная HTTP SESSION, которую я называю i18n_language.
3. Файл cookie, который я должен установить и получить, но я не знаю, как именно
4.HTTP-заголовок, который я мог получить, и здесь я тоже точно не знаю, и я смотрю, как djnango делает это с помощью удобного get_language_from_request
, который я использовал раньше, а теперь я перестал импортировать django, и я все еще хочу эта функция для моего кода, основанного теперь на webapp2.
def get_language_from_request(self, request):
"""
Analyzes the request to find what language the user wants the system to
show. If the user requests a sublanguage where we have a main language, we send
out the main language.
"""
if self.request.get('hl'):
self.session['i18n_language'] = self.request.get('hl')
return self.request.get('hl')
if self.session:
lang_code = self.session.get('i18n_language', None)
if lang_code:
logging.info('language found in session')
return lang_code
lang_code = Cookies(self).get(LANGUAGE_COOKIE_NAME)
if lang_code:
logging.info('language found in cookies')
return lang_code
accept = os.environ.get('HTTP_ACCEPT_LANGUAGE', '')
for accept_lang, unused in self.parse_accept_lang_header(accept):
logging.info('accept_lang:'+accept_lang)
lang_code = accept_lang
return lang_code
Я вижу, что код django доступен, но я не знаю, сколько делает i18n из webapp2, например, нужно ли мне позаботиться об откате для таких языков, как pt-br, должен вернуться к pt, если его нет. mo локализация для pt-br и аналогичные для других диалектов.
На самом деле настройку языка я могу сделать с помощью
i18n.get_i18n (). Set_locale (language)
Я прошу вашей помощи сделать приоритетными различные способы получения языка пользователя, и я также хотел бы знать свои идеи, как продолжить реализацию. Или вы думаете, что я могу просто использовать переменную сеанса и не так тщательно подходить к «полному» решению, поскольку я все равно в основном исправляю язык для географического использования, где мои единственные фактически используемые переводы сейчас - это бразильский португальский и английский, но я хочу он хорошо подготовлен к переключению на испанский и русский, а также на другие языки, поэтому я хотел бы иметь возможность переключиться на язык пользователя и, по крайней мере, сохранить его в сеансе webapp2 и знать, что вы думаете об использовании также cookie и заголовка, чтобы получить пользователя язык.
Исходный код, который я использовал для si от django, выглядит так, и я больше не могу его использовать, потому что он привязан к файлам django.mo и специфичен для django
def get_language_from_request(request):
"""
Analyzes the request to find what language the user wants the system to
show. Only languages listed in settings.LANGUAGES are taken into account.
If the user requests a sublanguage where we have a main language, we send
out the main language.
"""
global _accepted
from django.conf import settings
globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
supported = dict(settings.LANGUAGES)
if hasattr(request, 'session'):
lang_code = request.session.get('django_language', None)
if lang_code in supported and lang_code is not None and check_for_language(lang_code):
return lang_code
lang_code = request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME)
if lang_code and lang_code not in supported:
lang_code = lang_code.split('-')[0] # e.g. if fr-ca is not supported fallback to fr
if lang_code and lang_code in supported and check_for_language(lang_code):
return lang_code
accept = request.META.get('HTTP_ACCEPT_LANGUAGE', '')
for accept_lang, unused in parse_accept_lang_header(accept):
if accept_lang == '*':
break
# We have a very restricted form for our language files (no encoding
# specifier, since they all must be UTF-8 and only one possible
# language each time. So we avoid the overhead of gettext.find() and
# work out the MO file manually.
# 'normalized' is the root name of the locale in POSIX format (which is
# the format used for the directories holding the MO files).
normalized = locale.locale_alias.get(to_locale(accept_lang, True))
if not normalized:
continue
# Remove the default encoding from locale_alias.
normalized = normalized.split('.')[0]
if normalized in _accepted:
# We've seen this locale before and have an MO file for it, so no
# need to check again.
return _accepted[normalized]
for lang, dirname in ((accept_lang, normalized),
(accept_lang.split('-')[0], normalized.split('_')[0])):
if lang.lower() not in supported:
continue
langfile = os.path.join(globalpath, dirname, 'LC_MESSAGES',
'django.mo')
if os.path.exists(langfile):
_accepted[normalized] = lang
return lang
return settings.LANGUAGE_CODE
Можно ли делать это для каждого запроса? И я думаю, что я должен также установить заголовок на язык self.response.headers ['Content-Language'] = language
Согласно моим ожиданиям, я могу взять некоторую функцию непосредственно из django, если я решу использовать заголовки http, но я не понимаю, что они делают, поэтому, возможно, вы можете объяснить это код для меня из django:
def parse_accept_lang_header(lang_string):
"""
Parses the lang_string, which is the body of an HTTP Accept-Language
header, and returns a list of (lang, q-value), ordered by 'q' values.
Any format errors in lang_string results in an empty list being returned.
"""
result = []
pieces = accept_language_re.split(lang_string)
if pieces[-1]:
return []
for i in range(0, len(pieces) - 1, 3):
first, lang, priority = pieces[i : i + 3]
if first:
return []
priority = priority and float(priority) or 1.0
result.append((lang, priority))
result.sort(lambda x, y: -cmp(x[1], y[1]))
return result
Спасибо
Я обнаружил, что не могу использовать сеансы в функции инициализации обработчика запросов, возможно, это потому, что объект сеанса еще не создан. Поэтому я поместил код для получения языка из сеанса в функцию рендеринга BaseHandler, и, похоже, он работает. Также было бы неплохо рассмотреть заголовки или значение cookie.