From cdae91d72b7bfa5edb26e12e721891a3ce2f2aa7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Mon, 19 Apr 2010 08:58:54 +0000 Subject: Pass along translate function to templates. --- repoze/bfg/i18n.py | 96 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 32 deletions(-) (limited to 'repoze/bfg/i18n.py') diff --git a/repoze/bfg/i18n.py b/repoze/bfg/i18n.py index bc0ae4423..6fa809bf6 100644 --- a/repoze/bfg/i18n.py +++ b/repoze/bfg/i18n.py @@ -1,32 +1,48 @@ +import re + from zope.interface import implements from zope.interface import classProvides from repoze.bfg.interfaces import ITranslator from repoze.bfg.interfaces import ITranslatorFactory +from repoze.bfg.interfaces import IChameleonTranslate + from repoze.bfg.threadlocal import get_current_registry from repoze.bfg.threadlocal import get_current_request -def get_translator(request): - try: - reg = request.registry - except AttributeError: - reg = get_current_registry() - - if reg is None: # pragma: no cover - return None # only in insane circumstances +def get_translator(request, translator_factory=None): + """ Return a :term:`translator` for the given request based on the + :term:`translator factory` registered for the current application + and the :term:`request` passed in as the request object. If no + translator factory was sent to the + :class:`repoze.bfg.configuration.Configurator` constructor at + application startup, this function will return ``None``. + Note that the translation factory will only be called once per + request instance. + """ + translator = getattr(request, '_bfg_translator', None) if translator is False: return None if translator is None: - translator_factory = reg.queryUtility(ITranslatorFactory) + if translator_factory is None: + try: + reg = request.registry + except AttributeError: + reg = get_current_registry() + if reg is None: # pragma: no cover + return None # only in insane circumstances + translator_factory = reg.queryUtility(ITranslatorFactory) + if translator_factory is None: request_value = False else: translator = translator_factory(request) request_value = translator + try: request._bfg_translator = request_value except AttributeError: # pragma: no cover @@ -41,8 +57,8 @@ class InterpolationOnlyTranslator(object): self.request = request def __call__(self, message): - mapping = getattr(message, 'mapping', {}) #should be a TranslationString - return message % mapping + mapping = getattr(message, 'mapping', None) + return interpolate(message, mapping) class TranslationString(unicode): __slots__ = ('msgid', 'domain', 'mapping') @@ -61,27 +77,43 @@ class TranslationString(unicode): def __getstate__(self): return unicode(self), self.msgid, self.domain, self.mapping -def chameleon_translate(text, domain=None, mapping=None, context=None, - target_language=None, default=None): - if text is None: - return None - translator = None - request = get_current_request() - if request is not None: - request.chameleon_target_language = target_language - translator = get_translator(request) - if default is None: - default = text - if mapping is None: - mapping = {} - if translator is None: - return unicode(default) % mapping - if not isinstance(text, TranslationString): - text = TranslationString(default, msgid=text, domain=domain, - mapping=mapping) - return translator(text) +class ChameleonTranslate(object): + implements(IChameleonTranslate) + def __init__(self, translator_factory): + self.translator_factory = translator_factory + + def __call__(self, text, domain=None, mapping=None, context=None, + target_language=None, default=None): + if text is None: + return None + translator = None + request = get_current_request() + if request is not None: + request.chameleon_target_language = target_language + translator = get_translator(request, self.translator_factory) + if default is None: + default = text + if mapping is None: + mapping = {} + if translator is None: + return unicode(default) % mapping + if not isinstance(text, TranslationString): + text = TranslationString(default, msgid=text, domain=domain, + mapping=mapping) + return translator(text) +NAME_RE = r"[a-zA-Z][-a-zA-Z0-9_]*" + +_interp_regex = re.compile(r'(?