Ticket #150 (closed task: fixed)
Use Aquarium code for parsing user's preferred language settings
| Reported by: | jjinux | Owned by: | bbangert |
|---|---|---|---|
| Priority: | normal | Milestone: | 0.9.5 |
| Component: | I18N & Unicode | Version: | 0.9.3 |
| Severity: | normal | Keywords: | i18n |
| Cc: | ianb@…, dds |
Description (last modified by bbangert) (diff)
Here are some chunks of the appropriate code:
def initGetText(self): """Initialize gettext. Use the class API so that "_" is not globally installed. Add the following to ``self._ctx``: ``translation``, ``_``, ``gettext``, ``ngettext``. If ``properties.USE_GETTEXT`` is False, ``gettext.NullTranslations``. That way, your code will work even if you use ``_()`` with gettext turned off. """ # It's unnecessary to cache translation instances. The gettext module # already does that. ctx = self._ctx if properties.USE_GETTEXT: from gettext import translation ctx.translation = translation( languages=self.getLanguagePreferences(), *properties.GETTEXT_ARGS, **properties.GETTEXT_KWARGS) else: from gettext import NullTranslations ctx.translation = NullTranslations() ctx.gettext = ctx.translation.gettext ctx.ngettext = ctx.translation.ngettext ctx._ = ctx.gettext def getLanguagePreferences(self): """Return a list of preferred languages, most preferred first. The list may be empty. By default, just use parseAcceptLanguage_ on the ``ACCEPT_LANGUAGE`` header. The list will be passed to ``filterLanguagePreferences``. .. _parseAcceptLanguage: aquarium.parse.AcceptLanguage-module.html#parseAcceptLanguage """ from aquarium.parse.AcceptLanguage import parseAcceptLanguage acceptLanguage = self._ctx.wsa.getCgiEnv().get("HTTP_ACCEPT_LANGUAGE") languages = parseAcceptLanguage(acceptLanguage) self.filterLanguagePreferences(languages) return languages def filterLanguagePreferences(self, languages): """Update the ``languages`` list by applying additional logic. If not None, use ``properties.GETTEXT_ULTIMATE_FALLBACK`` (which defaults to "en-us") as an ultimate fallback. That means it gets appended to the list of languages if it isn't already there. It also means that if it's in the list of languages, everything after it is deleted. This deleting behavior is strange but useful. Normally, everything in the code is in "en-us". However, the "en-us" translation catalog is usually empty. If the user requests ``["en-us", "zh-cn"]`` and a translation isn't found for a string in "en-us", you don't want gettext to fallback to "zh-cn". You want it to just use the string itself. Hence, if a string isn't found in the ``properties.GETTEXT_ULTIMATE_FALLBACK`` catalog, the string in the source code will be used. """ ultimate = getattr(properties, "GETTEXT_ULTIMATE_FALLBACK", "en-us") if not ultimate: return if ultimate not in languages: languages.append(ultimate) index = languages.index(ultimate) languages[index+1:] = []
and, most importantly:
"""Parse the ``Accept-Language`` header.""" __docformat__ = "restructuredtext" # Created: Thu Apr 28 02:52:11 PDT 2005 # Author: Shannon -jj Behrens # Email: jjinux@users.sourceforge.net # # Copyright (c) Shannon -jj Behrens. All rights reserved. import re languageRegEx = re.compile(r"^[a-z]{2}(-[a-z]{2})?$", re.I) def parseAcceptLanguage(header=None): """Parse the ``Accept-Language`` header. Return a list of language tags sorted by their "q" values. For example, "en-us,en;q=0.5" should return ``["en-us", "en"]``. If there is no ``Accept-Language`` header present, default to ``[]``. """ if header is None: return [] langs = header.split(",") qs = [] for lang in langs: pieces = lang.split(";") lang, params = pieces[0].strip().lower(), pieces[1:] if not languageRegEx.match(lang): continue q = 1 for param in params: lvalue, rvalue = param.split("=") lvalue = lvalue.strip().lower() rvalue = rvalue.strip() if lvalue == "q": q = float(rvalue) qs.append((lang, q)) qs.sort(lambda a, b: -cmp(a[1], b[1])) return [lang for (lang, q) in qs]
If you have any questions, just ask!
Change History
Note: See
TracTickets for help on using
tickets.