Пример #1
0
 def translate(self,
               msgid,
               mapping=None,
               context=None,
               target_language=None,
               default=None):
     """
         Implementation of ITranslationDomain.translate using portal_i18n
     """
     try:
         site = context['PARENTS'][0].getSite()
     except AttributeError:
         # not in INySite context, fallback to identity translation
         return interpolate(default or msgid, mapping)
     tool = site.getPortalI18n()
     if target_language is None:
         available = tool.get_lang_manager().getAvailableLanguages()
         target_language = tool.get_negotiator().getLanguage(
             available, context)
     if default is not None:
         raw = tool.get_message_catalog().gettext(msgid,
                                                  target_language,
                                                  default=default)
     else:
         raw = tool.get_message_catalog().gettext(msgid, target_language)
     return interpolate(raw, mapping)
    def translate(self, msgid, mapping=None, context=None,
                  target_language=None, default=None):
        """See interface `ITranslationDomain`"""
        if target_language is None and context is not None:
            avail_langs = self.getAvailableLanguages()
            # Let's negotiate the language to translate to. :)
            negotiator = zope.component.getUtility(INegotiator, context=self)
            target_language = negotiator.getLanguage(avail_langs, context)

        # Get the translation. Default is the source text itself.
        if target_language is not None:
            catalog_names = self._catalogs.get(target_language, [])
        else:
            catalog_names = []

        for name in catalog_names:
            catalog = super(TranslationDomain, self).__getitem__(name)
            text = catalog.queryMessage(msgid)
            if text is not None:
                break
        else:
            # If nothing found, delegate to a translation server higher up the
            # tree.
            domain = zope.component.queryNextUtility(self, ITranslationDomain,
                                                     self.domain)
            if domain is not None:
                return domain.translate(msgid, mapping, context,
                                        target_language, default=default)
            if default is None:
                default = unicode(msgid)
            text = default

        # Now we need to do the interpolation
        return interpolate(text, mapping)
        def notify(self, obj, user, what, label,
                           get_users_extra_bindings,
                           mail_template_extra_bindings,
                           mail_template_options):

            portal_membership = getToolByName(obj, 'portal_membership')
            member = portal_membership.getMemberById(user)
            if member is not None:
                timestamp = datetime.now().isoformat()
                annotations = IAnnotations(member)
                sticky_messages = annotations.get(SSMKEY, {})

                # Create mapping for interpolation
                mapping = {
                    'u': obj.absolute_url(),
                    't': obj.Title(),
                    's': mail_template_options['current_state'],
                    'm': str(mail_template_options.get('member'))
                }

                msg = interpolate(_messages[what], mapping)

                mdict= {
                    'type': 'info',
                    'message': msg,
                    'timestamp': timestamp,
                    }
                sticky_messages[timestamp] = mdict
                annotations[SSMKEY] = sticky_messages
                return 1
            return 0
    def fast_translate(msgid,
                       domain=None,
                       mapping=None,
                       context=None,
                       target_language=None,
                       default=None):
        if msgid is None:
            return

        if target_language is not None:
            result = translate(msgid,
                               domain=domain,
                               mapping=mapping,
                               context=context,
                               target_language=target_language,
                               default=default)
            if result != msgid:
                return result

        if isinstance(msgid, Message):
            default = msgid.default
            mapping = msgid.mapping

        if default is None:
            default = str(msgid)

        if not isinstance(default, basestring):
            return default

        return interpolate(default, mapping)
Пример #5
0
    def translate(self,
                  msgid,
                  mapping=None,
                  context=None,
                  target_language=None,
                  default=None,
                  msgid_plural=None,
                  default_plural=None,
                  number=None):
        '''See interface ITranslationDomain'''
        # Find out what the target language should be
        if target_language is None and context is not None:
            langs = [m[0] for m in self.messages.keys()]
            # Let's negotiate the language to translate to. :)
            negotiator = getUtility(INegotiator)
            target_language = negotiator.getLanguage(langs, context)

        # Find a translation; if nothing is found, use the default
        # value
        if default is None:
            default = text_type(msgid)
        text = self.messages.get((target_language, msgid))
        if text is None:
            text = default
        return interpolate(text, mapping)
    def date_format(self, time, formatstring):
        # This is a simplified version of Products.CMFPlone.i18nl10n.ulocalized_time
        # that can take any format string.

        # ${a}        Locale's abbreviated weekday name.
        # ${A}        Locale's full weekday name.
        # ${b}        Locale's abbreviated month name.
        # ${B}        Locale's full month name.
        # ${d}        Day of the month as a decimal number [01,31].
        # ${H}        Hour (24-hour clock) as a decimal number [00,23].
        # ${I}        Hour (12-hour clock) as a decimal number [01,12].
        # ${m}        Month as a decimal number [01,12].
        # ${M}        Minute as a decimal number [00,59].
        # ${p}        Locale's equivalent of either AM or PM.
        # ${S}        Second as a decimal number [00,61].
        # ${y}        Year without century as a decimal number [00,99].
        # ${Y}        Year with century as a decimal number.
        # ${Z}        Time zone name (no characters if no time zone exists).

        # get the format elements used in the formatstring
        mapping = {}
        formatelements = _interp_regex.findall(formatstring)
        # reformat the ${foo} to foo
        formatelements = [el[2:-1] for el in formatelements]

        # add used elements to mapping
        elements = [e for e in formatelements if e in datetime_formatvariables]

        # add weekday name, abbr. weekday name, month name, abbr month name
        week_included = True
        month_included = True

        name_elements = [e for e in formatelements if e in name_formatvariables]
        if not ('a' in name_elements or 'A' in name_elements):
            week_included = False
        if not ('b' in name_elements or 'B' in name_elements):
            month_included = False

        for key in elements:
            mapping[key]=time.strftime('%'+key)

        if week_included:
            weekday = int(time.strftime('%w')) # weekday, sunday = 0
            if 'a' in name_elements:
                mapping['a']=weekdayname_msgid_abbr(weekday)
            if 'A' in name_elements:
                mapping['A']=weekdayname_msgid(weekday)
        if month_included:
            monthday = int(time.strftime('%m')) # month, january = 1
            if 'b' in name_elements:
                mapping['b']=monthname_msgid_abbr(monthday)
            if 'B' in name_elements:
                mapping['B']=monthname_msgid(monthday)

        # translate translateable elements
        for key in name_elements:
            mapping[key] = translate(mapping[key], 'plonelocales', context=self.request, default=mapping[key])

        # Apply the data to the format string:
        return interpolate(formatstring, mapping)
Пример #7
0
class NyI18nTranslator(object):

    implements(ITranslationDomain)

    def translate(self,
                  msgid,
                  mapping=None,
                  context=None,
                  target_language=None,
                  default=None):
        try:
            site = context['PARENTS'][0].getSite()
        except KeyError, e:
            # malformed Request, probably we are in a mock/testing env.
            return msgid
        tool = site.getPortalI18n()
        if target_language is None:
            available = tool.get_portal_lang_manager().getAvailableLanguages()
            target_language = tool.get_negotiator().getLanguage(
                available, context)
        if default is not None:
            raw = tool.get_message_catalog().gettext(msgid,
                                                     target_language,
                                                     default=default)
        else:
            raw = tool.get_message_catalog().gettext(msgid, target_language)
        return interpolate(raw, mapping)
Пример #8
0
 def translate(self,
               msgid,
               mapping=None,
               context=None,
               target_language=None,
               default=None):
     """ """
     msgstr = self.gettext(msgid, lang=target_language, default=default)
     return interpolate(msgstr, mapping)
Пример #9
0
    def translate(self, msgid, domain=None, mapping=None, default=None):
        options = self.contexts['options']

        lang = options.get('_lang', None)
        translate = options.get('_translate', None)
        if translate is None:
            translate = lambda msgid, lang: msgid

        msg = translate(msgid, lang=lang)
        return interpolate(msg, mapping)
Пример #10
0
    def translate(self, msgid, domain=None, mapping=None, default=None):
        options = self.contexts['options']

        lang = options.get('_lang', None)
        translate = options.get('_translate', None)
        if translate is None:
            translate = lambda msgid, lang: msgid

        msg = translate(msgid, lang)
        return interpolate(msg, mapping)
Пример #11
0
 def translate(self, msgid, mapping=None, context=None,
               target_language=None, default=None):
     """ """
     msgstr = self.gettext(msgid, lang=target_language, default=default)
     # BBB support str in mapping by converting to unicode for
     # backward compatibility.
     if mapping:
         mapping = dict([to_unicode(k), to_unicode(v)]
                         for k, v in mapping.iteritems())
     return interpolate(msgstr, mapping)
Пример #12
0
 def translate(self, msgid, mapping=None, context=None,
               target_language=None, default=None):
     """ """
     msgstr = self.gettext(msgid, lang=target_language, default=default)
     # BBB support str in mapping by converting to unicode for
     # backward compatibility.
     if mapping:
         mapping = dict([to_unicode(k), to_unicode(v)]
                         for k, v in mapping.iteritems())
     return interpolate(msgstr, mapping)
    def translate(self, msgid, mapping=None, context=None,
                  target_language=None, default=None):
        pts = queryUtility(IPlacelessTranslationService)
        try:
            if pts is not None:
                return pts.translate(self.domain, msgid, mapping, context,
                                     target_language, default)
        except ConnectionStateError:
            pass

        return interpolate(default, mapping)
Пример #14
0
    def _recursive_translate(self, msgid, mapping, target_language, default, context, seen=None):
        """Recursively translate msg."""
        # MessageID attributes override arguments
        if isinstance(msgid, Message):
            if msgid.domain != self.domain:
                return translate(msgid, msgid.domain, mapping, context, target_language, default)
            default = msgid.default
            mapping = msgid.mapping

        # Recursively translate mappings, if they are translatable
        if mapping is not None and Message in (type(m) for m in mapping.values()):
            if seen is None:
                seen = set()
            seen.add(msgid)
            mapping = mapping.copy()
            for key, value in mapping.items():
                if isinstance(value, Message):
                    # TODO Why isn't there an IMessage interface?
                    # https://bugs.launchpad.net/zope3/+bug/220122
                    if value in seen:
                        raise ValueError("Circular reference in mappings detected: %s" % value)
                    mapping[key] = self._recursive_translate(value, mapping, target_language, default, context, seen)

        if default is None:
            default = unicode(msgid)

        # Get the translation. Use the specified fallbacks if this fails
        catalog_names = self._catalogs.get(target_language)
        if catalog_names is None:
            for language in self._fallbacks:
                catalog_names = self._catalogs.get(language)
                if catalog_names is not None:
                    break

        text = default
        if catalog_names:
            if len(catalog_names) == 1:
                # this is a slight optimization for the case when there is a
                # single catalog. More importantly, it is extremely helpful
                # when testing and the test language is used, because it
                # allows the test language to get the default.
                text = self._data[catalog_names[0]].queryMessage(msgid, default)
            else:
                for name in catalog_names:
                    catalog = self._data[name]
                    s = catalog.queryMessage(msgid)
                    if s is not None:
                        text = s
                        break

        # Now we need to do the interpolation
        if text and mapping:
            text = interpolate(text, mapping)
        return text
Пример #15
0
 def translate(self, msgid, mapping=None, context=None, target_language=None,
               default=None):
     """
     * `context` is used in negotiaton - IUserPreferredLanguages(context)
     * `mapping` requires interpolation process
     """
     if target_language is None:
         #target_language = negotiate(self.context.get_languages(), context)
         target_language = lang_negotiator(self.get_languages())
     text = self.gettext(msgid, target_language, default)
     return interpolate(text, mapping)
Пример #16
0
    def translate(self, msgid, mapping=None, context=None, target_language=None, default=None):
        """See zope.i18n.interfaces.ITranslationDomain"""

        # if the msgid is empty, let's save a lot of calculations and return
        # an empty string.
        if msgid == u"":
            return u""

        if target_language is None and context is not None:
            langs = self._catalogs.keys()
            # invoke local or global unnamed 'INegotiator' utilities
            negotiator = getUtility(INegotiator)
            # try to determine target language from negotiator utility
            target_language = negotiator.getLanguage(langs, context)

        # MessageID attributes override arguments
        if isinstance(msgid, (Message, MessageID)):
            if msgid.domain != self.domain:
                util = getUtility(ITranslationDomain, msgid.domain)
            mapping = msgid.mapping
            default = msgid.default

        if default is None:
            default = msgid

        # Get the translation. Use the specified fallbacks if this fails
        catalog_names = self._catalogs.get(target_language)
        if catalog_names is None:
            for language in self._fallbacks:
                catalog_names = self._catalogs.get(language)
                if catalog_names is not None:
                    break

        text = default
        if catalog_names:
            if len(catalog_names) == 1:
                # this is a slight optimization for the case when there is a
                # single catalog. More importantly, it is extremely helpful
                # when testing and the test language is used, because it
                # allows the test language to get the default.
                text = self._data[catalog_names[0]].queryMessage(msgid, default)
            else:
                for name in catalog_names:
                    catalog = self._data[name]
                    s = catalog.queryMessage(msgid)
                    if s is not None:
                        text = s
                        break

        # Now we need to do the interpolation
        if text and mapping:
            text = interpolate(text, mapping)
        return text
Пример #17
0
    def get_translation(self, msg, _default=None, **kwargs):
        """
        Translate message in selected language using Message Catalog
        and substitute named identifiers with values supplied by kwargs mapping

        Most commonly used - a straight forward complete translation
        in selected language.

        """
        lang = kwargs.get('lang') or self.get_selected_language()
        msg = self.get_message_catalog().gettext(msg, lang, default=_default)
        return interpolate(msg, kwargs)
Пример #18
0
 def translate(self, msgid, mapping=None, context=None, target_language=None,
               default=None):
     """
         Implementation of ITranslationDomain.translate using portal_i18n
     """
     try:
         site = context['PARENTS'][0].getSite()
     except AttributeError:
         # not in INySite context, fallback to identity translation
         return interpolate(default or msgid, mapping)
     tool = site.getPortalI18n()
     if target_language is None:
         available = tool.get_lang_manager().getAvailableLanguages()
         target_language = tool.get_negotiator().getLanguage(available,
                                                             context)
     if default is not None:
         raw = tool.get_message_catalog().gettext(msgid, target_language,
                                          default=default)
     else:
         raw = tool.get_message_catalog().gettext(msgid, target_language)
     return interpolate(raw, mapping)
Пример #19
0
    def get_translation(self, msg, _default=None, **kwargs):
        """
        Translate message in selected language using Message Catalog
        and substitute named identifiers with values supplied by kwargs mapping

        Most commonly used - a straight forward complete translation
        in selected language.

        """
        lang = kwargs.get('lang') or self.get_selected_language()
        msg = self.get_message_catalog().gettext(msg, lang, default=_default)
        return interpolate(msg, kwargs)
Пример #20
0
    def translate(self, msgid, mapping=None, context=None,
                  target_language=None, default=None):

        pts  = getTranslationService()
        if pts is None or context is None:
            # If we don't have enough context use interpolate
            return interpolate(default, mapping)

        # Don't accept anything which isn't a real request
        if not IBrowserRequest.providedBy(context) or 'PARENTS' not in context:
            raise ValueError, "You didn't pass in a request as the context."

        parent = context['PARENTS'][-1]
        return pts.translate(self.domain, msgid, mapping, parent,
                             target_language, default)
Пример #21
0
    def translate(self,
                  msgid,
                  mapping=None,
                  context=None,
                  target_language=None,
                  default=None):
        pts = queryUtility(IPlacelessTranslationService)
        try:
            if pts is not None:
                return pts.translate(self.domain, msgid, mapping, context,
                                     target_language, default)
        except ConnectionStateError:
            pass

        return interpolate(default, mapping)
Пример #22
0
def pester_answerer(event):
    # Place an annotation on the member that will cause sticky-status messages
    # to display a notice

    # Stubbing out this method for a demo
    return

    request = getattr(event.object, 'REQUEST', None)
    if not request:
        return
    if not ISlcUnderflow.providedBy(request):
        return

    try:
        pm = getToolByName(event.object, 'portal_membership')
    except AttributeError:
        # seldom case of zope user in event.object that cannot acquire portal tools
        return
    pc = getToolByName(event.object, 'portal_catalog')
    userid = event.object.getUserId()
    member = pm.getMemberById(userid)

    # Find questions we need to answer
    brains = pc(portal_type='slc.underflow.question', inforequest=True)

    for brain in brains:
        if userid not in brain.commentators:
            # XXX This code really belongs in some utililty inside
            # slc.stickystatusmessages
            timestamp = datetime.now().isoformat()
            annotations = IAnnotations(member)
            sticky_messages = annotations.get(SSMKEY, {})

            mapping = { 'u': brain.getURL() }
            msg = _(u'An information request is waiting for your response. '
                u'Click <a href="${u}">here</a> to respond to it now.')
            msg = interpolate(msg, mapping)

            mdict= {
                'type': 'info',
                'message': msg,
                'timestamp': timestamp,
                }
            sticky_messages[timestamp] = mdict
            annotations[SSMKEY] = sticky_messages
Пример #23
0
    def translate(self, msgid, mapping=None, context=None,
                  target_language=None, default=None):
        '''See interface ITranslationDomain'''
        # Find out what the target language should be
        if target_language is None and context is not None:
            langs = [m[0] for m in self.messages.keys()]
            # Let's negotiate the language to translate to. :)
            negotiator = getUtility(INegotiator)
            target_language = negotiator.getLanguage(langs, context)

        # Find a translation; if nothing is found, use the default
        # value
        if default is None:
            default = msgid
        text = self.messages.get((target_language, msgid))
        if text is None:
            text = default
        return interpolate(text, mapping)
    def translate(self,
                  msgid,
                  mapping=None,
                  context=None,
                  target_language=None,
                  default=None):
        """See interface `ITranslationDomain`"""
        if target_language is None and context is not None:
            avail_langs = self.getAvailableLanguages()
            # Let's negotiate the language to translate to. :)
            negotiator = zope.component.getUtility(INegotiator, context=self)
            target_language = negotiator.getLanguage(avail_langs, context)

        # Get the translation. Default is the source text itself.
        if target_language is not None:
            catalog_names = self._catalogs.get(target_language, [])
        else:
            catalog_names = []

        for name in catalog_names:
            catalog = super(TranslationDomain, self).__getitem__(name)
            text = catalog.queryMessage(msgid)
            if text is not None:
                break
        else:
            # If nothing found, delegate to a translation server higher up the
            # tree.
            domain = zope.component.queryNextUtility(self, ITranslationDomain,
                                                     self.domain)
            if domain is not None:
                return domain.translate(msgid,
                                        mapping,
                                        context,
                                        target_language,
                                        default=default)
            if default is None:
                default = unicode(msgid)
            text = default

        # Now we need to do the interpolation
        return interpolate(text, mapping)
Пример #25
0
    def fast_translate(msgid, domain=None, mapping=None, context=None, target_language=None, default=None):
        if msgid is None:
            return

        if target_language is not None:
            result = translate(
                msgid, domain=domain, mapping=mapping, context=context, target_language=target_language, default=default
            )
            if result != msgid:
                return result

        if isinstance(msgid, Message):
            default = msgid.default
            mapping = msgid.mapping

        if default is None:
            default = unicode(msgid)

        if not isinstance(default, basestring):
            return default

        return interpolate(default, mapping)
Пример #26
0
def smart_translate(msgid, domain=None, mapping=None, context=None,
                   target_language=None, default=None):
    """ target_language is expected to be the http accept-language header
    """
    if msgid is None:
        return

    if target_language is not None:
        return translate(
            msgid, domain=domain, mapping=mapping, context=target_language,
            target_language=None, default=default)

    if isinstance(msgid, Message):
        default = msgid.default
        mapping = msgid.mapping

    if default is None:
        default = unicode(msgid)

    if not isinstance(default, basestring):
        return default

    return interpolate(default, mapping)
Пример #27
0
    def date_format(self, time, formatstring):
        # This is a simplified version of
        # Products.CMFPlone.i18nl10n.ulocalized_time
        # that can take any format string.

        # ${a}        Locale's abbreviated weekday name.
        # ${A}        Locale's full weekday name.
        # ${b}        Locale's abbreviated month name.
        # ${B}        Locale's full month name.
        # ${d}        Day of the month as a decimal number [01,31].
        # ${H}        Hour (24-hour clock) as a decimal number [00,23].
        # ${I}        Hour (12-hour clock) as a decimal number [01,12].
        # ${m}        Month as a decimal number [01,12].
        # ${M}        Minute as a decimal number [00,59].
        # ${p}        Locale's equivalent of either AM or PM.
        # ${S}        Second as a decimal number [00,61].
        # ${y}        Year without century as a decimal number [00,99].
        # ${Y}        Year with century as a decimal number.
        # ${Z}        Time zone name (no characters if no time zone exists).

        # get the format elements used in the formatstring
        mapping = {}
        formatelements = _interp_regex.findall(formatstring)
        # reformat the ${foo} to foo
        formatelements = [el[2:-1] for el in formatelements]

        # add used elements to mapping
        elements = [e for e in formatelements if e in datetime_formatvariables]

        # add weekday name, abbr. weekday name, month name, abbr month name
        week_included = True
        month_included = True

        name_elements = [
            e for e in formatelements if e in name_formatvariables
        ]
        if not ('a' in name_elements or 'A' in name_elements):
            week_included = False
        if not ('b' in name_elements or 'B' in name_elements):
            month_included = False

        for key in elements:
            mapping[key] = time.strftime('%' + key)

        if week_included:
            weekday = int(time.strftime('%w'))  # weekday, sunday = 0
            if 'a' in name_elements:
                mapping['a'] = weekdayname_msgid_abbr(weekday)
            if 'A' in name_elements:
                mapping['A'] = weekdayname_msgid(weekday)
        if month_included:
            monthday = int(time.strftime('%m'))  # month, january = 1
            if 'b' in name_elements:
                mapping['b'] = monthname_msgid_abbr(monthday)
            if 'B' in name_elements:
                mapping['B'] = monthname_msgid(monthday)

        # translate translateable elements
        for key in name_elements:
            mapping[key] = translate(mapping[key],
                                     'plonelocales',
                                     context=self.request,
                                     default=mapping[key])

        # Apply the data to the format string:
        return interpolate(formatstring, mapping)
Пример #28
0
    def _recursive_translate(self,
                             msgid,
                             mapping,
                             target_language,
                             default,
                             context,
                             msgid_plural,
                             default_plural,
                             number,
                             seen=None):
        """Recursively translate msg."""
        # MessageID attributes override arguments
        if isinstance(msgid, Message):
            if msgid.domain != self.domain:
                return translate(msgid, msgid.domain, mapping, context,
                                 target_language, default, msgid_plural,
                                 default_plural, number)
            default = msgid.default
            mapping = msgid.mapping
            msgid_plural = msgid.msgid_plural
            default_plural = msgid.default_plural
            number = msgid.number

        # Recursively translate mappings, if they are translatable
        if (mapping is not None
                and Message in (type(m) for m in mapping.values())):
            if seen is None:
                seen = set()
            seen.add((msgid, msgid_plural))
            mapping = mapping.copy()
            for key, value in mapping.items():
                if isinstance(value, Message):
                    # TODO Why isn't there an IMessage interface?
                    # https://bugs.launchpad.net/zope3/+bug/220122
                    if (value, value.msgid_plural) in seen:
                        raise ValueError(
                            "Circular reference in mappings detected: %s" %
                            value)
                    mapping[key] = self._recursive_translate(
                        value, mapping, target_language, default, context,
                        msgid_plural, default_plural, number, seen)

        if default is None:
            default = text_type(msgid)
        if msgid_plural is not None and default_plural is None:
            default_plural = text_type(msgid_plural)

        # Get the translation. Use the specified fallbacks if this fails
        catalog_names = self._catalogs.get(target_language)
        if catalog_names is None:
            for language in self._fallbacks:
                catalog_names = self._catalogs.get(language)
                if catalog_names is not None:
                    break

        text = default
        if catalog_names:
            if len(catalog_names) == 1:
                # this is a slight optimization for the case when there is a
                # single catalog. More importantly, it is extremely helpful
                # when testing and the test language is used, because it
                # allows the test language to get the default.
                if msgid_plural is not None:
                    # This is a plural
                    text = self._data[catalog_names[0]].queryPluralMessage(
                        msgid, msgid_plural, number, default, default_plural)
                else:
                    text = self._data[catalog_names[0]].queryMessage(
                        msgid, default)
            else:
                for name in catalog_names:
                    catalog = self._data[name]
                    if msgid_plural is not None:
                        # This is a plural
                        s = catalog.queryPluralMessage(msgid, msgid_plural,
                                                       number, default,
                                                       default_plural)
                    else:
                        s = catalog.queryMessage(msgid)
                    if s is not None:
                        text = s
                        break

        # Now we need to do the interpolation
        if text and mapping:
            text = interpolate(text, mapping)
        return text
Пример #29
0
    def _recursive_translate(  # noqa
            self,
            msgid,
            mapping,
            target_language,
            default,
            context,
            plural=None, n=None, seen=None):
        """Recursively translate msg."""
        # MessageID attributes override arguments
        if isinstance(msgid, Message):
            if msgid.domain != self.domain:
                return translate(msgid, msgid.domain, mapping, context,
                                 target_language, default, plural, n)
            default = msgid.default
            if mapping is None:
                mapping = msgid.mapping

        # Recursively translate mappings, if they are translatable
        mapping_values = None
        if mapping is not None:
            mapping_values = (type(m) for m in mapping.values())
        if (mapping is not None and Message in mapping_values):
            if seen is None:
                seen = set()
            seen.add(msgid)
            mapping = mapping.copy()
            for key, value in mapping.items():
                if isinstance(value, Message):
                    if value in seen:
                        raise ValueError(
                            'Circular reference in mappings detected: '
                            '{0}'.format(value)
                        )
                    mapping[key] = self._recursive_translate(
                        value, value.mapping, target_language,
                        value.default, context, value.plural, n, seen)

        if default is None:
            default = unicode(msgid)

        # Get the translation. Use the specified fallbacks if this fails
        catalog_names = self._catalogs.get(target_language)
        if catalog_names is None:
            for language in self._fallbacks:
                catalog_names = self._catalogs.get(language)
                if catalog_names is not None:
                    break

        text = default
        if catalog_names:
            if len(catalog_names) == 1:
                # this is a slight optimization for the case when there is a
                # single catalog. More importantly, it is extremely helpful
                # when testing and the test language is used, because it
                # allows the test language to get the default.
                text = self._data[catalog_names[0]].queryMessage(
                    msgid, default, None, n)
            else:
                for name in catalog_names:
                    catalog = self._data[name]
                    s = catalog.queryMessage(msgid)
                    if s is not None:
                        text = s
                        break

        # Now we need to do the interpolation
        if text and mapping:
            text = interpolate(text, mapping)
        return text
Пример #30
0
def translate(
        msgid, domain=None, mapping=None, context=None, target_language=None,
        default=None, plural=None, n=None):
    """Translate text.

    First setup some test components:

    >>> from zope import component, interface
    >>> import zope.i18n.interfaces

    >>> class TestDomain:
    ...     interface.implements(zope.i18n.interfaces.ITranslationDomain)  # noqa
    ...
    ...     def __init__(self, **catalog):
    ...         self.catalog = catalog
    ...
    ...     def translate(self, text, *_, **__):
    ...         return self.catalog[text]

    Normally, the translation system will use a domain utility:

    >>> component.provideUtility(TestDomain(eek=u'ook'), name='my.domain')
    >>> translate(u'eek', 'my.domain')
    u'ook'

    Normally, if no domain is given, or if there is no domain utility
    for the given domain, then the text isn't translated:

    >>> translate(u'eek')
    u'eek'

    Moreover the text will be converted to unicode:

    >>> translate('eek', 'your.domain')
    u'eek'

    A fallback domain factory can be provided. This is normally used
    for testing:

    >>> def fallback(domain=u''):
    ...     return TestDomain(eek=u'test-from-' + domain)
    >>> interface.directlyProvides(  # noqa
    ...     fallback,
    ...     zope.i18n.interfaces.IFallbackTranslationDomainFactory,
    ...     )

    >>> component.provideUtility(fallback)

    >>> translate(u'eek')
    u'test-from-'

    >>> translate(u'eek', 'your.domain')
    u'test-from-your.domain'
    """
    if isinstance(msgid, Message):
        domain = msgid.domain
        default = msgid.default
        if mapping is None:
            mapping = msgid.mapping

    if default is None:
        default = unicode(msgid)

    if domain:
        util = queryUtility(ITranslationDomain, domain)
        if util is None:
            util = queryUtility(IFallbackTranslationDomainFactory)
            if util is not None:
                util = util(domain)
    else:
        util = queryUtility(IFallbackTranslationDomainFactory)
        if util is not None:
            util = util()

    if util is None:
        return interpolate(default, mapping)

    if target_language is None and context is not None:
        target_language = negotiate(context)

    return util.translate(
        msgid, mapping, context, target_language, default, plural, n,
    )
Пример #31
0
 def translate(self, msgid, mapping=None, context=None,
               target_language=None, default=None):
     """ """
     msgstr = self.gettext(msgid, lang=target_language, default=default)
     return interpolate(msgstr, mapping)