Honor user's browser language (#558)

Previously we would attempt to satisfy the user's first language
preference, immediately falling back to english if that was not
possible. Now, we will get the best match of the user's preferred
languages.

This requires storing the available locales on app startup, so we
have mg_globals.available_locales ready to compare them against the
list of preferred user languages.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2012-12-02 00:29:30 +01:00
parent 7b9f9d1edb
commit 6ef75af50e
5 changed files with 33 additions and 12 deletions

View File

@ -31,7 +31,7 @@ from mediagoblin.mg_globals import setup_globals
from mediagoblin.init.celery import setup_celery_from_config
from mediagoblin.init.plugins import setup_plugins
from mediagoblin.init import (get_jinja_loader, get_staticdirector,
setup_global_and_app_config, setup_workbench, setup_database,
setup_global_and_app_config, setup_locales, setup_workbench, setup_database,
setup_storage, setup_beaker_cache)
from mediagoblin.tools.pluginapi import PluginManager
@ -68,6 +68,9 @@ class MediaGoblinApp(object):
# Setup other connections / useful objects
##########################################
# load all available locales
setup_locales()
# Set up plugins -- need to do this early so that plugins can
# affect startup.
_log.info("Setting up plugins.")

View File

@ -19,6 +19,7 @@ from beaker.util import parse_cache_config_options
import jinja2
from mediagoblin.tools import staticdirect
from mediagoblin.tools.translate import get_available_locales
from mediagoblin.init.config import (
read_mediagoblin_config, generate_validation_report)
from mediagoblin import mg_globals
@ -37,6 +38,11 @@ class ImproperlyConfigured(Error):
pass
def setup_locales():
"""Checks which language translations are available and sets them"""
setup_globals(available_locales=get_available_locales())
def setup_global_and_app_config(config_path):
global_config, validation_result = read_mediagoblin_config(config_path)
app_config = global_config['mediagoblin']

View File

@ -45,6 +45,8 @@ workbench_manager = None
# A thread-local scope
thread_scope = threading.local()
# a list of translated locales
available_locales = None
# gettext (this will be populated on demand with gettext.Translations)
thread_scope.translations = None

View File

@ -20,7 +20,7 @@ from babel.localedata import exists
from mediagoblin import mg_globals
from mediagoblin import messages
from mediagoblin.tools import common
from mediagoblin.tools.translate import setup_gettext
from mediagoblin.tools.translate import get_gettext_translation
from mediagoblin.meddleware.csrf import render_csrf_form_token
@ -34,7 +34,7 @@ def get_jinja_env(template_loader, locale):
(In the future we may have another system for providing theming;
for now this is good enough.)
"""
setup_gettext(locale)
mg_globals.thread_scope.translations = get_gettext_translation(locale)
# If we have a jinja environment set up with this locale, just
# return that one.

View File

@ -16,7 +16,9 @@
import gettext
import pkg_resources
from babel.localedata import exists
from babel import localedata
from babel.support import LazyProxy
from mediagoblin import mg_globals
@ -30,6 +32,15 @@ TRANSLATIONS_PATH = pkg_resources.resource_filename(
'mediagoblin', 'i18n')
def get_available_locales():
"""Return a list of locales for which we have translations"""
locales=[]
for locale in localedata.list():
if gettext.find('mediagoblin', TRANSLATIONS_PATH, [locale]):
locales.append(locale)
return locales
def locale_to_lower_upper(locale):
"""
Take a locale, regardless of style, and format it like "en_US"
@ -76,15 +87,15 @@ def get_locale_from_request(request):
# TODO: We need a list of available locales, and match with the list
# of accepted locales, and serve the best available locale rather than
# the most preferred, or fall back to 'en' immediately.
target_lang = request.accept_languages.best
return locale_to_lower_upper(target_lang)
target_lang = request.accept_languages.best_match(
mg_globals.available_locales)
return locale_to_lower_upper(target_lang)
SETUP_GETTEXTS = {}
def setup_gettext(locale):
def get_gettext_translation(locale):
"""
Setup the gettext instance based on this locale
Return the gettext instance based on this locale
"""
# Later on when we have plugins we may want to enable the
# multi-translations system they have so we can handle plugin
@ -97,10 +108,9 @@ def setup_gettext(locale):
else:
this_gettext = gettext.translation(
'mediagoblin', TRANSLATIONS_PATH, [locale], fallback=True)
if exists(locale):
if localedata.exists(locale):
SETUP_GETTEXTS[locale] = this_gettext
mg_globals.thread_scope.translations = this_gettext
return this_gettext
def pass_to_ugettext(*args, **kwargs):