summaryrefslogtreecommitdiff
path: root/repoze/bfg/i18n.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2010-04-19 08:58:54 +0000
committerChris McDonough <chrism@agendaless.com>2010-04-19 08:58:54 +0000
commitcdae91d72b7bfa5edb26e12e721891a3ce2f2aa7 (patch)
tree5345a838f8f1aa868f8dc1d819ba1d034f9375c3 /repoze/bfg/i18n.py
parentf5c6c574ada26ec0b2766f5ca20bb2b5b7393ec5 (diff)
downloadpyramid-cdae91d72b7bfa5edb26e12e721891a3ce2f2aa7.tar.gz
pyramid-cdae91d72b7bfa5edb26e12e721891a3ce2f2aa7.tar.bz2
pyramid-cdae91d72b7bfa5edb26e12e721891a3ce2f2aa7.zip
Pass along translate function to templates.
Diffstat (limited to 'repoze/bfg/i18n.py')
-rw-r--r--repoze/bfg/i18n.py96
1 files changed, 64 insertions, 32 deletions
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'(?<!\$)(\$(?:(%(n)s)|{(%(n)s)}))'
+ % ({'n': NAME_RE}))
-
-
+def interpolate(text, mapping=None):
+ def replace(match):
+ whole, param1, param2 = match.groups()
+ return unicode(mapping.get(param1 or param2, whole))
+
+ if not text or not mapping:
+ return text
+
+ return _interp_regex.sub(replace, text)