summaryrefslogtreecommitdiff
path: root/repoze/bfg/i18n.py
diff options
context:
space:
mode:
Diffstat (limited to 'repoze/bfg/i18n.py')
-rw-r--r--repoze/bfg/i18n.py202
1 files changed, 0 insertions, 202 deletions
diff --git a/repoze/bfg/i18n.py b/repoze/bfg/i18n.py
deleted file mode 100644
index adbdb1db6..000000000
--- a/repoze/bfg/i18n.py
+++ /dev/null
@@ -1,202 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2004 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-
-import re
-
-from zope.interface import implements
-from zope.interface import classProvides
-
-from zope.i18nmessageid import Message
-
-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
-
-class TranslationString(Message):
- """ The constructor for a :term:`translation string`. This
- constructor accepts one required argument named ``text``.
- ``text`` must be the default text of the translation string,
- optionally including replacement markers such as ``${foo}``.
-
- Optional keyword arguments to the TranslationString constructor
- include ``msgid``, ``mapping`` and ``domain``.
-
- ``mapping``, if supplied, must be a dictionarylike object which
- represents the replacement values for any replacement markers
- found within the ``text`` value of this
-
- ``msgid`` represents an explicit :term:`message identifier` for
- this translation string. Usually, the ``text`` of a translation
- string serves as its message identifier. However, using this
- option you can pass an explicit message identifier, usually a
- simple string. This is useful when the ``text`` of a translation
- string is too complicated or too long to be used as a translation
- key. If ``msgid`` is ``None`` (the default), the ``msgid`` value
- used by this translation string will be assumed to be the value of
- ``text``.
-
- ``domain`` represents the :term:`translation domain`. By default,
- the translation domain is ``None``, indicating that this
- translation string is associated with no translation domain.
-
- After a translation string is constructed, its ``text`` value is
- available as the ``default`` attribute of the object, the
- ``msgid`` is available as the ``msgid`` attribute of the object,
- the ``domain`` is available as the ``domain`` attribute, and the
- ``mapping`` is available as the ``mapping`` attribute.
- """
- def __new__(cls, text, mapping=None, msgid=None, domain=None):
- if msgid is None:
- msgid = text
- return Message.__new__(cls, msgid, domain=domain, default=text,
- mapping=mapping)
-
-class TranslationStringFactory(object):
- """ Create a factory which will generate translation strings
- without requiring that each call to the factory be passed a
- ``domain`` value. The ``domain`` value passed to this class'
- constructor will be used as the ``domain`` values of
- :class:`repoze.bfg.i18n.TranslationString` objects generated by
- the ``__call__`` of this class. The ``text``, ``mapping``, and
- ``msgid`` values provided to ``__call__`` have the meaning as
- described by the constructor of the
- :class:`repoze.bfg.i18n.TranslationString`"""
- def __init__(self, domain):
- self.domain = domain
-
- def __call__(self, text, mapping=None, msgid=None):
- return TranslationString(text, mapping=mapping, msgid=msgid,
- domain=self.domain)
-
-bfg_tstr = TranslationStringFactory('bfg')
-bfg_tstr.__doc__ = """\
- A :class:`repoze.bfg.i18n.TranslationStringFactory` instance with
- a default ``domain`` value of ``bfg``. This object may be called
- with the values ``text``, ``mapping``, and ``msgid`` as per the
- documentation of the
- :class:`repoze.bfg.i18n.TranslationStringFactory` class."""
-
-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 a very simple
- default 'interpolation only' translator.
-
- Note that the translation factory will only be constructed once
- per request instance.
- """
-
- translator = getattr(request, '_bfg_translator', None)
-
- if translator is None:
-
- if translator_factory is None:
- try:
- reg = request.registry
- except AttributeError:
- reg = get_current_registry()
- translator_factory = reg.queryUtility(
- ITranslatorFactory,
- default=InterpolationOnlyTranslator)
-
- translator = translator_factory(request)
-
- try:
- request._bfg_translator = translator
- except AttributeError: # pragma: no cover
- pass # it's only a cache
-
- return translator
-
-class InterpolationOnlyTranslator(object):
-
- """ A class implementing the :term:`translator factory` interface
- as its constructor and the :term:`translator` interface as its
- ``__call__`` method. Useful as a minimal translator factory, this
- class only does basic interpolation of mapping values; it does not
- actually do any language translations and ignores all
- :term:`translation domain` information. To use it explicitly::
-
- from repoze.bfg.configuration import Configurator
- from repoze.bfg.i18n import InterpolationOnlyTranslator
- config = Configurator(translator_factory=InterpolationOnlyTranslator)
-
- An instance of this class is returned by
- :func:`repoze.bfg.i18n.get_translator` if no explicit translator
- factory is registered.
- """
- classProvides(ITranslatorFactory)
- implements(ITranslator)
- def __init__(self, request):
- self.request = request
-
- def __call__(self, message):
- mapping = getattr(message, 'mapping', None)
- return interpolate(message, mapping)
-
-class ChameleonTranslate(object):
- """ Registered as a Chameleon translate function 'under the hood'
- to allow our ITranslator and ITranslatorFactory to drive template
- translation."""
- 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
- if default is None:
- default = text
- if mapping is None:
- mapping = {}
- if not hasattr(text, 'mapping'):
- text = TranslationString(default, mapping=mapping, msgid=text,
- domain=domain)
- translator = self.make_translator(target_language)
- return translator(text)
-
- def make_translator(self, target_language):
- translator = None
- request = get_current_request()
- if request is not None:
- translator = get_translator(request, self.translator_factory)
- if translator is None:
- translator = InterpolationOnlyTranslator(request)
- return translator
-
-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):
- """ Interpolate a string with one or more *replacement markers*
- (``${foo}`` or ``${bar}``). Note that if a :term:`translation
- string` is passed to this function, it will be implicitly
- converted back to the Unicode object."""
- 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)