Back to index

plone3  3.1.7
negotiator.py
Go to the documentation of this file.
00001 from zope.component import queryUtility
00002 from zope.i18n.interfaces import INegotiator
00003 from zope.i18n.negotiator import normalize_langs
00004 from zope.interface import implements
00005 
00006 from persistent.list import PersistentList
00007 
00008 from plone.i18n.locales.interfaces import IContentLanguageAvailability
00009 from plone.i18n.negotiator.default import DefaultLanguage
00010 from plone.i18n.negotiator.interfaces import ILanguageFallback
00011 
00012 
00013 class Negotiator(PersistentList):
00014 
00015     implements(INegotiator)
00016 
00017     def __init__(self):
00018         super(Negotiator, self).__init__()
00019         self.append(DefaultLanguage)
00020 
00021     def getLanguage(self, langs, request):
00022         # langs are the available languages from the translation domains
00023         userlangs = []
00024 
00025         for plugin_registration in self:
00026             plugin = plugin_registration(request)
00027             userlangs = plugin.getPreferredLanguages()
00028             # Stop once we got a result from a plugin
00029             if userlangs is not None:
00030                 break
00031 
00032         if userlangs is None:
00033             return None
00034 
00035         # Restrict the languages based on site-wide policy
00036         allowed = queryUtility(IContentLanguageAvailability)
00037         if allowed is not None:
00038             langs = [str(lang) for lang in allowed.getAvailableLanguages()]
00039 
00040         langs = normalize_langs(langs)
00041         fallback = queryUtility(ILanguageFallback)
00042 
00043         for lang in userlangs:
00044             if lang in langs:
00045                 return langs.get(lang)
00046 
00047             # If the user asked for a specific variation, but we don't
00048             # have it available we may serve the most generic one,
00049             # according to the spec (eg: user asks for ('en-us',
00050             # 'de'), but we don't have 'en-us', then 'en' is preferred
00051             # to 'de').
00052             if fallback is not None:
00053                 fallbacks = fallback.fallback(lang)
00054                 for fb in fallbacks:
00055                     if fb in langs:
00056                         return fb
00057 
00058         return None