Viewing file: i18n.py (5.95 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
from zope.interface import implements
from nevow import inevow
def languagesFactory(ctx): header = inevow.IRequest(ctx).getHeader('accept-language') if header is None: return [] langs = [] for lang in header.split(','): quality = 1.0 if ';' in lang: lang, quality = lang.split(';', 1) if quality[:2] == 'q=': try: quality = float(quality[2:]) except ValueError: pass langs.append((quality, lang)) if '-' in lang: langs.append((quality, lang.split('-')[0])) langs.sort(lambda a,b: cmp(b[0], a[0])) return [lang for quality, lang in langs]
class I18NConfig(object): implements(inevow.II18NConfig)
def __init__(self, domain=None, localeDir=None, ): self.domain = domain self.localeDir = localeDir class PlaceHolder(object): def __init__(self, translator, *args, **kwargs): self.translator = translator self.args = args self.kwargs = kwargs _mod = kwargs.pop('_mod', None) if _mod is None: _mod = [] self.mod = _mod
def __mod__(self, other): kw = {} kw.update(self.kwargs) kw['_mod'] = self.mod+[other] return self.__class__(self.translator, *self.args, **kw)
def __repr__(self): args = [] if self.args: args.append('*%r' % (self.args,)) args.append('translator=%r' % self.translator) if self.kwargs: args.append('**%r' % self.kwargs) s = '%s(%s)' % ( self.__class__.__name__, ', '.join(args), ) for mod in self.mod: s += ' %% %r' % (mod,) return s
def flattenL10n(placeHolder, ctx): kw = placeHolder.kwargs
try: languages = inevow.ILanguages(ctx) except TypeError: pass else: kw = dict(kw) # copy before we mutate it kw['languages'] = languages
try: cfg = inevow.II18NConfig(ctx) except TypeError: pass else: kw = dict(kw) # copy before we mutate it if cfg.domain is not None: kw['domain'] = cfg.domain if cfg.localeDir is not None: kw['localeDir'] = cfg.localeDir
s = placeHolder.translator(*placeHolder.args, **kw) for mod in placeHolder.mod: s = s % mod return s
class Translator(object): """ A gettext-like Translator for Nevow.
The major difference between this and naive gettext is that with Translator, the actual translation is done as part of Nevow's flattening process, allowing per-user settings to be retrieved via the context.
@ivar translator: the actual translation function to use.
@ivar args: positional arguments to pass to translator.
@ivar kwargs: keyword arguments to pass to translator.
@ivar gettextFunction: If using the default translator function, name of GNU gettext function to wrap. Useful for 'ungettext'. """ translator = None args = None kwargs = None
gettextFunction = 'ugettext'
def _gettextTranslation(self, *args, **kwargs): domain = kwargs.pop('domain', None) localeDir = kwargs.pop('localeDir', None) languages = kwargs.pop('languages', None) import gettext translation = gettext.translation( domain=domain, localedir=localeDir, languages=languages, fallback=True, ) fn = getattr(translation, self.gettextFunction) return fn(*args, **kwargs)
def __init__(self, **kwargs): """ Initialize.
@keyword translator: the translator function to use.
@keyword gettextFunction: The GNU gettext function to wrap. See class docstring.
@param kwargs: keyword arguments for the translator function. """ translator = kwargs.pop('translator', None) if translator is not None: self.translator = translator if self.translator is None: self.translator = self._gettextTranslation
gettextFunction = kwargs.pop('gettextFunction', None) if gettextFunction is not None: self.gettextFunction = gettextFunction
self.kwargs = kwargs
def __call__(self, *args, **kwargs): """ Translate a string.
@param args: arguments to pass to translator, usually the string to translate, or for things like ungettext two strings and a number.
@param kwargs: keyword arguments for the translator. Arguments given here will override the ones given at initialization.
@return: a placeholder that will be translated when flattened.
@rtype: PlaceHolder """ kw = dict(self.kwargs) kw.update(kwargs) return PlaceHolder(self.translator, *args, **kw)
_ = Translator()
ungettext = Translator(gettextFunction='ungettext')
def render(translator=None): """ Render a localised message.
>>> from nevow import i18n, rend >>> class MyPage(rend.Page): ... render_i18n = i18n.render()
or, to use a specific domain:
>>> from nevow import i18n, rend >>> _ = i18n.Translator(domain='foo') >>> class MyPage(rend.Page): ... render_i18n = i18n.render(translator=_)
""" if translator is None: translator = _
def _render(page, ctx, data): # TODO why does this get page? Is it # the Page's self? Why would this look # like a bound method? children = ctx.tag.children ctx.tag.clear() for child in children: if isinstance(child, basestring): child = translator(child) ctx.tag[child] return ctx.tag
return _render
# TODO also provide macro()
|