20

Does the new and recommended way to format strings available in Python 2.7 using format result in a non translated string in Django?

The strings are in the .po file, translated, but it won't be translated on the website. For example:

from django.utils.translation import ugettext as _

website_name = "Stackoverflow"
title = _(u"{sitename} is a good website".format(sitename=website_name))

The .po file after translating the string looks like this:

#: path/to/file.py:4
msgid "{sitename} is a good website"
msgstr "{sitename} ist eine gute Website"

After running django-admin.py compilemessages and restarting the webserver, on the processed HTML page it is still in english, while all the other strings are being translated. Furthermore, while all strings using format are not translated, strings formatted using the % operator are translated as expected. It is also not a gettext/ugettext issue, as the problem is the same with both functions.

Iodnas
  • 3,414
  • 24
  • 26
  • 13
    have you tried `_(u"{sitename} is a good website").format...` – jfs Jul 22 '12 at 17:59
  • This solved the problem. I was searching for hours for a solution before asking here, so thanks a lot for your quick and helpful reply. Why did you post it as a comment and not as an answer? – Iodnas Jul 22 '12 at 18:08
  • Doesn't apply to OP, but note about `format`: `Python’s str.format() method will not work when either the format_string or any of the arguments to str.format() contains lazy translation objects.` https://docs.djangoproject.com/en/1.11/topics/i18n/translation/#formatting-strings-format-lazy – User Oct 05 '17 at 05:56

3 Answers3

12

compilemessages sees the string as "{sitename} is a good website", but when the app is running the string is actually e.g. "MySite is a good website", which of course doesn't have a translation. You must translate the bare string first, and then you can perform template operations on it.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 14
    For the sake of clarity, this would mean `_(u"{sitename} is a good website").format(sitename=website_name)` (note the different position of the parenthesis). This also works fine with `ugettext_lazy`, see also http://stackoverflow.com/questions/10999954/django-translations-and-gettext-the-deprecation-of-the-string-interpolation – Davide Feb 24 '15 at 08:31
3

The following should work:

_('Foo %(x)s') % {'x': "bar"}

s is the string, d is the intiger.

Artemis
  • 2,553
  • 7
  • 21
  • 36
Zvak
  • 41
  • 1
1

i had the same problem so i translated the text first and then added the dynamic content like

title = _(u"is a good website")
title = " ".join([website_name, title])

There must be a better way to do this

Rakesh
  • 81,458
  • 17
  • 76
  • 113
  • Thanks for the answer, but the dynamic part (placeholder) must be part of the string to allow a language specific placement within the phrase. In your solution it would be fix at the beginning of the string. – Iodnas Jul 22 '12 at 19:54