Translating %% with gettext and jinja2 and pyramid

我是研究僧i 提交于 2020-02-22 08:07:54

问题


Doing i18n work with Python using Jinja2 and Pyramid. Seems to have a problem knowing how it should translate %%. I'm beginning to suspect the bug is in Jinja2.


So I've done some more investigation and it appears the problem is more with gettext than with jinja2 as illustrated with the repl

>>>gettext.gettext("98%% off %s sale") % ('holiday')
'98% off holiday sale'
>>>gettext.gettext("98%% off sale")
'98%% off sale'

>>>gettext.gettext("98% off %s sale") % ('holiday')
Traceback (most recent call last):
  Python Shell, prompt 13, line 1
TypeError: %o format: a number is required, not str

It seems to be a chicken/egg problem.

  • If gettext translates %% -> % then the formatter blows up on it during parameter substitution.
  • If gettext doesn't translate %% -> % then when the formatter is not called (no params to insert) then the %% leaks out.

All this means the translators (most of whom are not computer programmers) have to be very careful in how they do the translation and everyone needs to be very careful with translations that include %.

Seems like we are doing this wrong (somehow) and there should be a more straightforward and uniform format for doing this. Right now we are coping by simply injecting a % as a format parameter.

Is there a better way to do this, or is this as good as it gets?


There is a .po file at the bottom

Unit test pretty much says it all, why is the last assertion failing? Is this a bug with Jinja2, or do I need to be dealing with this differently.

class Jinja2Tests(TestCase):

    def test_percent_percent(self):
        """ i18n(gettext) expresses  98% as 98%% only in some versions of jinja2 that has not
            worked as expected.  This is to make sure that it is working. """
        env = Environment(extensions=['jinja2.ext.i18n'])
        lang = gettext.translation('messages', path.abspath(path.join(path.dirname(__file__), 'data')))
        env.install_gettext_translations(lang)

        template = env.from_string(source="{{ _('98%% off %(name)s sale') | format(name='holiday') }}")
        result = template.render()
        self.assertEqual('98% off holiday sale(translated)', result)

        template = env.from_string(source="{{ _('98%% off sale') }}")
        result = template.render()

        # THE LINE BELOW FAILS WITH:
        # AssertionError: '98% off sale(translated)' != u'98%% off sale(translated)'
        self.assertEqual('98% off sale(translated)', result)

And the MO file you have to compile to a PO file to run the above code.

# This file is distributed under the same license as the Uniregistrar project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
#
msgid ""
msgstr ""
"Project-Id-Version: Uniregistrar 1.0\n"
"Report-Msgid-Bugs-To: mark@uniregistry.com\n"
"POT-Creation-Date: 2016-12-22 15:22-0500\n"
"PO-Revision-Date: 2016-11-14 16:42-0500\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n"
"Language-Team: en <LL@li.org>\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.3\n"

#: uniregistrar/constants.py:90
msgid "98%% off sale"
msgstr "98%% off sale(translated)"

#: uniregistrar/constants.py:90
msgid "98%% off %(name)s sale"
msgstr "98%% off %(name)s sale(translated)"

来源:https://stackoverflow.com/questions/41730770/translating-with-gettext-and-jinja2-and-pyramid

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!