Determine the user language in Pyramid
localization, pyramid, python
Solution
Pyramid doesn't dictate how a locale should be negotiated. Basing your site language on the "Accept-Language" header can cause problems as most users do not know how to set their preferred browser languages. Make sure your users can switch languages easily and use a cookie to store that preference for future visits.
You either need to set a `_LOCALE_` key on the request (via an event handler, for example), or provide your own custom locale negotiator.
Here's an example using the `NewRequest` event and the `accept_language` header, which is an instance of the 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')
Problem
I want to make internationalization for my project. I followed how it is described in official documentation, but localization still doesn't work. Here is how I try get user locale: ``` 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 ``` But `request` doesn't have attr "local_name", but it has "Accept-Language" and so when function `get_local_name` doesn't find "local_name" in the request, it calls another function: ``` 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 ``` How can I see `negotiator` try to get local from global environment but if it cant to do that its set value from config. And I cant understand why Pyramid doesn't get locale directly from request's field "Accept-Language"? And, how can I make a correct determination of the locale?