2012-06-30 14 views
13

私は自分のプロジェクトの国際化を行いたいと思います。私はそれが公式の文書に記載されている方法に従ったが、ローカリゼーションはまだ機能しない。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」を持っていますが、機能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は、地球環境からローカル取得しようとするが、それは設定から​​その設定値これを行うに傾けるかどうかを確認することができます、それは別の関数を呼び出します。 そして、なぜピラミッドがリクエストのフィールド「Accept-Language」から直接ロケールを取得しないのか理解できませんか?

そして、どうすればロケールを正しく決定できますか?

答えて

14

ピラミッドはロケールのネゴシエーション方法を指定しません。 「Accept-Language」ヘッダーにサイト言語を設定すると、ほとんどのユーザーが好みのブラウザ言語を設定する方法がわからないため、問題が発生する可能性があります。ユーザーが言語を簡単に切り替えることができ、将来の訪問のためにCookieを使用してその嗜好を保存できることを確認します。

_LOCALE_ key on the request(イベントハンドラなど)を設定するか、独自のcustom locale negotiatorを指定する必要があります。

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') 
+0

しかし、accept_language原因accept_languageはAccept()のallreadyインスタンスであり、best_match()メソッド自体は持っているオブジェクトを作成する必要はありません。それは多くのおかげでピラミッドバージョン1.2を試しています – Denis

+1

@Denis:あなたは確かに正しいです; 'accept_language'はすでに' Accept'のインスタンスです。修正されました。 –

+0

@Martijin Pietersとにかくありがとう、すべて正常に動作します)) – Denis

2

request._LOCALE_作品という理由だけでは、デフォルトではロケールの交渉がdefault_locale_negotiatorであることに注意してください:

はここNewRequest eventaccept_language headerを使用した例ですが、webob Accept classのインスタンスです。たとえば、クッキーが存在しない場合にDBからユーザーをフェッチする必要があるなど、非常に複雑なチェックがある場合、NewRequestハンドラーは変換を必要としない要求に対してオーバーヘッドを持ちます。ピラミッド1.5のよう

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) 
0

、あなたは現在のロケールにアクセスするには、これらの要求プロパティを使用することができます:

request.localizerLocalizer

request.localeのインスタンスを彼らのために、あなたも同じように、カスタムロケールの交渉を使用することができますと同じです。request.localizer.locale_name

関連する問題