4

いくつかの翻訳が利用可能なアプリケーションがあるとします。

AVAILABLE_LOCALES = ['en_US', 'en_EN', 'de_AT']

Accept-Languageヘッダーに従って最も適切なものを選択したいと思います。

 request.accept_languages.best_match の使用

ロケールを取得するには、次のように記述します。

@babel.localeselector
def get_locale():
    user = getattr(g, 'user', None)
    if user is not None:
        return user.locale
    return request.accept_languages.best_match(AVAILABLE_LOCALES)

問題は、ユーザー エージェントが を要求した場合、一致が失敗し、選択がデフォルト値 (英語) に戻りますが、明らかにde_DEを取得したい場合です。de_AT

注:ドキュメントページの例は次のとおりです

return request.accept_languages.best_match(['de', 'fr', 'en'])

en_ENただし、これは同じ言語の 2 つの異なるバージョン ( 、 )を許可しませんen_US

交渉_ロケールの使用

このGitHub の問題で、誰かが Babel のnegotiate_locale関数の使用を提案しています。

@babel.localeselector
def get_locale():
    user = getattr(g, 'user', None)
    if user is not None:
        return user.locale
    preferred = [x.replace('-', '_') for x in request.accept_languages.values()]
    return negotiate_locale(preferred, AVAILABLE_LOCALES)

しかし、知る限り、これですべてのユースケースが修正されるわけではありません。利用可能なロケール['de_AT', 'de']['en_US', 'en_EN', 'de_DE']. しかし、その逆ではありません:

negotiate_locale(['de_AT', 'de'], ['en_US', 'en_EN', 'de_DE'])  # returns de_DE
negotiate_locale(['de_DE', 'de'], ['en_US', 'en_EN', 'de_AT'])  # returns None

エイリアスのハードコーディングされたリストがde指すため、最初の方法が機能しde_DEます。

また、ブラウザが送信するだけで送信de_ATしない場合deも壊れていますが、これが一般的な構成かどうかはわかりません (次の段落を参照)。

これに対処する信頼できる方法はありますか?

 最新のブラウザの典型的な値?

サブ質問として、最新のブラウザーにどのような値を期待できるかを知りたいです。

ユーザーが間違ってカスタマイズしない限り、最新のブラウザーがAccept-Language[lang+territory, lang] のような形式の を送信すると仮定しても安全ですか?

['en-US', 'en']

また、Firefox のバージョンを試してみましたが、これは少し驚くべきことでした。

私のシステムのロケールはフランス語です:

locale
LANG=fr_FR.UTF-8
LANGUAGE=
LC_CTYPE="fr_FR.UTF-8"
LC_NUMERIC="fr_FR.UTF-8"
LC_TIME="fr_FR.UTF-8"
LC_COLLATE="fr_FR.UTF-8"
LC_MONETARY="fr_FR.UTF-8"
LC_MESSAGES="fr_FR.UTF-8"
LC_PAPER="fr_FR.UTF-8"
LC_NAME="fr_FR.UTF-8"
LC_ADDRESS="fr_FR.UTF-8"
LC_TELEPHONE="fr_FR.UTF-8"
LC_MEASUREMENT="fr_FR.UTF-8"
LC_IDENTIFICATION="fr_FR.UTF-8"
LC_ALL=

about:configページには次のように記載されています。

general.useragent.locale: en-US
intl.accept_languages: fr, fr-fr, en-us, en

テストFlaskアプリに接続すると、

print(request.accept_languages.values())
# ['en_US', 'en']

したがって、提案されたもの@babel.localeselectorは英語のロケールを返します。

Chromium を使用して同じ値を取得します。

ブラウザの設定が間違っていますか?

4

0 に答える 0