Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#27221 closed Cleanup/optimization (fixed)

Document how to escape a percent symbol in ugettext

Reported by: Paolo Dente Owned by: Henry Dang
Component: Documentation Version: master
Severity: Normal Keywords: ugettext percent
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

While {% trans %} and {% blocktrans %} correctly escape '%' with '%%' in templates, using ugettext or ugettext_lazy does not; this results in errors with compilemessages.

Example:

price_adjust = models.DecimalField(max_digits=5, decimal_places=2, default=1, choices=(('0.90', _('10% discount'), ))

will generate:

#, python-format
msgid "10% discount"
msgstr ""

When this is translated to German escaping the %, like:

#, python-format
msgid "10% discount"
msgstr "10%% Rabatt"

This results in an error message:

Execution of msgfmt failed: /vagrant/src/locale_files/en/LC_MESSAGES/django.po:xxx: number of format specifications in 'msgid' and 'msgstr' does not match

On the other hand, when it's not escaped, the error becomes:

Execution of msgfmt failed: /vagrant/src/locale_files/en/LC_MESSAGES/django.po:xxx: 'msgstr' is not a valid Python format string, unlike 'msgid'. Reason: In the directive number 1, the character 'R' is not a valid conversion specifier.

Also, while trying to find a solution for this, I've found this suggestion: https://code.djangoproject.com/ticket/24257#comment:2 - which doesn't work for me at all. The only way I found is to use %(percent)s in the string, which is awkward and difficult to read by the actual translators.

Change History (10)

comment:1 Changed 3 years ago by Tim Graham

Not sure about the correct resolution. All I could find was a workaround on Stackoverflow.

comment:2 Changed 3 years ago by Claude Paroz

Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization
Version: 1.8master

This is not Django specific and this is a documentation issue. There are two solutions that I know of:

  • Escape the literal % by doubling it in the string yourself.
  • Add a comment on the line before the translatable string containing xgettext:no-python-format.

comment:3 Changed 3 years ago by Tim Graham

Component: InternationalizationDocumentation
Summary: ugettext does not escape percent symbolDocument how to escape a percent symbol in ugettext

comment:4 Changed 3 years ago by Henry Dang

Owner: changed from nobody to Henry Dang
Status: newassigned

comment:5 Changed 3 years ago by Henry Dang

comment:6 Changed 3 years ago by Claude Paroz

Has patch: set
Patch needs improvement: set

The explanation in the patch is not correct. The fix must happen in the original file, not in the .po file.

comment:7 Changed 3 years ago by Henry Dang

Patch needs improvement: unset

Ah, you're right. I've made the changes.

Last edited 3 years ago by Henry Dang (previous) (diff)

comment:8 Changed 3 years ago by Tim Graham

Triage Stage: AcceptedReady for checkin

comment:9 Changed 3 years ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In b1a90415:

Fixed #27221 -- Doc'd how to escape a percent symbol in ugettext().

comment:10 Changed 3 years ago by Tim Graham <timograham@…>

In 047a62b3:

[1.10.x] Fixed #27221 -- Doc'd how to escape a percent symbol in ugettext().

Backport of b1a9041535db5d03dab7f205669f0ab7a47de854 from master

Note: See TracTickets for help on using tickets.
Back to Top