13

我想为我的项目进行国际化。我按照官方文档中的描述进行了操作,但是本地化仍然不起作用。这是我尝试获取用户语言环境的方法:

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没有属性“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尝试从全局环境中获取本地,但如果它不能从配置中执行它的设置值。而且我不明白为什么 Pyramid 不能直接从请求的“Accept-Language”字段中获取语言环境?

而且,我怎样才能正确确定语言环境?

4

3 回答 3

15

Pyramid 并没有规定应该如何协商语言环境。将您的站点语言基于“Accept-Language”标题可能会导致问题,因为大多数用户不知道如何设置他们首选的浏览器语言。确保您的用户可以轻松切换语言并使用 cookie 存储该偏好以供将来访问。

您需要_LOCALE_在请求上设置一个键(例如,通过事件处理程序),或者提供您自己的自定义语言环境 negotiator

这是一个使用NewRequest事件accept_languageheader的示例,它是webobAccept的一个实例:

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')
于 2012-06-30T13:52:35.570 回答
2

请注意,request._LOCALE_仅因为默认情况下语言环境协商器是default_locale_negotiator. 如果您有非常复杂的检查,例如,如果 cookie 不存在,您必须从数据库中获取用户,那么 NewRequest 处理程序对于不需要任何翻译的请求确实有开销。对于他们,您还可以使用自定义语言环境协商器,例如:

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)
于 2012-07-02T07:44:31.537 回答
0

从金字塔 1.5 开始,您可以使用这些请求属性来访问当前语言环境:

request.localizer的一个实例Localizer

request.locale如同request.localizer.locale_name

于 2015-01-14T08:18:26.150 回答