Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ugettext: How to deal with variables within a sentence?

Tags:

django

from django.utils.translation import ugettext_lazy as _

_(u"I am off to school at '%s' o'clock" % time)

This is kind of odd, since I would get a whole line to translate like this

"I am off to school at \'%s\' o'clock"

Now if the translator removes the \'%s\' by mistake, it would break the code.

Should I better separate the sentence into two parts? But this might give the translator trouble to understand the context of the sentence.

_(u"I am off to school at ") + '%s' + _(u"o'clock") % time

Is there a better approach to this?

like image 463
Houman Avatar asked Sep 10 '12 12:09

Houman


2 Answers

If you make use of named string interpolation as opposed to positional string interpolation, this should protect you from an exception if the translator forgets one of the parameters from his translated string.

An example from the django docs:

def my_view(request, m, d):
    output = _('Today is %(month)s %(day)s.') % {'month': m, 'day': d}
    return HttpResponse(output)

Note the dictionary of {'name': 'value'} pairs to be used in string substitution.

For this reason, you should use named-string interpolation (e.g., %(day)s) instead of positional interpolation (e.g., %s or %d) whenever you have more than a single parameter. If you used positional interpolation, translations wouldn't be able to reorder placeholder text.

(django docs)

like image 157
Niel Thiart Avatar answered Sep 23 '22 02:09

Niel Thiart


First, it should be _(u"I am off to school at '%s' o'clock") % time, because the string is grep and translated before the value of time is available at runtime.

Second, you could protect your code by wrapping it w/ try...except or using string.Template.safe_substitute:

from string import Template 

# for ugettext
Template(ugettext(u"I am off to school at '$time' o'clock")).safe_substitute(time=time)

# for ugettext_lazy
from django.utils.encodings import force_unicode
Template(force_unicode(ugettext_lazy(u"I am off to school at '$time' o'clock"))).safe_substitute(time=time)

# shortcut
def safe_trans(msg, **kwargs):
    return Template(force_unicode(msg)).safe_substitute(kwargs)
safe_trans(_("I am off to school at '$time' o'clock"), time=12)
like image 43
okm Avatar answered Sep 22 '22 02:09

okm